This question already has answers here:
Double vs Decimal Rounding in C#
(2 answers)
Closed 5 years ago.
I should write a program that the input is double (variable called money), and I should print separately the digits before the decimal point and the digits after.
for example:
for the input: 36.5 should print: The number before the decimal point is: 36 The number after decimal point is: 5
for the input: 25.4 should print: The number before the decimal point is: 24 The number after decimal point is: 4
Console.WriteLine("Enter money:");
double money = double.Parse(Console.ReadLine());
int numBeforePoint = (int)money;
double numAfterPoint = (money - (int)money)*10;
Console.WriteLine("The number beforethe decimal point is: {0}. the number after the decimal point is: {1}",numBeforePoint,numAfterPoint);
If I enter 25.4 it prints: The number before the decimal point is: 24 The number after decimal point is: 3.9999999
I don't want 3.999999 I want 4
You should use decimal to represent numeric types, rather than doubles - it's what they were designed for!
You've been the victim of a floating point error, where the value you're assigning to a floating point value can't be exactly represented with its precision (the .999... you get is the closest value it can represent).
decimals have a lower range than doubles, but much higher precision - this means they're more likely to be able to represent the values you're assigning. See here or the linked decimal documentation page for more details.
Note that a more conventional way of getting the decimal part involves Math.Truncate (which by the way will work for negative values as well):
decimal numAfterPoint = (money - Math.Truncate(money))*10;
Probably easiest to use the string representation of the decimal, and use substring before and after the index of '.'
Something like this:
string money = Console.ReadLine();
int decimalIndex = money.IndexOf('.');
string numBeforePoint = money.Substring(0, decimalIndex);
string numAfterPoint = money.Substring(decimalIndex + 1);
Then you can parse the string representations as needed.
Try this:
static string Foo(double d)
{
var str = d.ToString(CultureInfo.InvariantCulture).Split('.');
var left = str[0];
var right = str[1];
return $"The number before the decimal point is: {left} The number after decimal point is: {right}";
}
using System.Linq;
public static string GetDecimalRemainder(double d)
{
return d.ToString(CultureInfo.InvariantCulture).Split('.').Last();
{
Using LINQ is much more convenient in my opinion.
Related
I have this C# code which calculate compound interest plus principal amount every year.
static void CompoundInterest(double principal, double interestRate, double years, double annualCompound)
{
var total = 0.0;
for (int t = 1; t < years + 1; t++)
{
total = principal * Math.Pow((1 + interestRate / annualCompound),
(annualCompound * t));
Console.Write("Your Total for Year {0} "
+ "is {1}. \n", t, total);
}
}
When I tested it with
CompoundInterest(1000, 0.05, 3, 12);
and the output is
Your Total for Year 1 is 1051.161897881733.
Your Total for Year 2 is 1104.941335558327.
Your Total for Year 3 is 1161.4722313334678.
How should I round it accurately? Another question is Math.Pow uses double but in financial calculation, we need decimal. How do I fix this? Convert into decimal after Math.Pow?
I made some test by rounding first and converting to decimal and by converting to decimal and then rounding afterword. Both gave the same results.
But from the logic point of view, I would convert first than rounding after words. This way I will have better control of testing what is converted and what is rounded.
For converting there are different answers, but I found this method Convert.ToDecimal is supported by all .net frameworks and cores.
ex. decimal value = Convert.ToDecimal(double_value);
And then you decimal.Round, which some one has asked and got answer here Why does .NET use banker's rounding as default?
Just in case reference to Floating-point numeric types.
You can convert a double to a decimal directly if you'd like
decimal decimalTotal = (decimal)total;
As for rounding, there is a built-in function, Math.Round, that takes a variety of number formats. It has a overload to specify how many decimal points you want.
decimal roundedDecimal = Math.Round(decimalTotal, 2);
I have a string that can be up to 9 characters long including an optional decimal point but all the others will be numbers. It could be "123456789" or "12.345678", for example.
What variable type should I convert it to so that I can use it in calculations?
And how do I do that?
float.Parse("12.345678");
or
float.Parse("12.345678", CultureInfo.InvariantCulture.NumberFormat);
For avoiding these kind of outputs:
1.524157875019e+16
8.10000007371e-9
For integers you can checkout this link also: https://msdn.microsoft.com/en-us/library/bb397679.aspx
You should convert it to float, double or decimal, depending on how big the numbers become.
You can use Parse() or TryParse() to parse a string to an arithmetic type.
string numberString = "123456789";
double number;
if (!double.TryParse(numberString, out number))
{
// There was an error parsing ...
// Ex. report the error back or whatever ...
// You can also set a default value for it ...
// Ex. number = 0;
}
// Use number ...
It's a question of precision and a bit of memory consumption.
if the floating point remainder is important to you use one of the following:
float - 4 bytes, 7 digits precision
Double - 8 bytes, 15-16 digits precision
Decimal - 16 bytes , 28-29 digits precision
I need a double value to contain 2 digits after ".", such as 2.15, 20.15. If the input value is 3.125, then it should print an error message.
My code is:
private static bool isTwoDigits(double num)
{
return (num - Math.Floor(num)).ToString().Length <= 4;
}
If you input 2.15, then it will be 2.15 -2 = 0.15 <= 4 - which works. But when I change num to 20.15 it doesn't, because (num - Math.Floor(num)) here will return 0.14999999999.
Any other good ideas?
This is the nature of binary floating points number. Just like 1/3 can't be exactly written out as a finite decimal number, 0.1 can't be exactly represented by a finite binary expansion.
So depending on what you are trying to achieve exactly, you could:
If you are validating some string input (e.g. a textbox), you can process the information at the string level, e.g. with a RegEx.
You can store your numbers in the decimal datatype, which can store decimal values exactly.
You can do your computation on a double but you have to give yourself a tolerance. If you expect only 2 digits of precision, you can do something like Math.Abs(x - Math.Round(x, 2)) < 0.00000001). The definition of this tolerance margin depends on your use case.
If you're really worried about the number of decimal places, on a base-10 number, use decimal instead of double.
the decimal is for calculating financial calculations, and the reason it's called decimal in the first place is so that it can better handle base-10 calculations such as dollars and cents.
And you can also check if the number is 2 digits a bit more simply.
return num % 0.01m == 0.0m;
SO as has already been said, you can use regexp to ensure the entire format is correct.
But if you know there will only be 1 decimal because its already a number you can also just use String.IndexOf
eg
double foo = .... ;
string fooString = foo.ToString();
if (fooString.Length - fooString.IndexOf(".") != 3) => error.
(Its 3 because Length is max index + 1 )
This question already has answers here:
Why am I getting the wrong result when using float? [duplicate]
(4 answers)
Float is converting my values
(4 answers)
Closed 9 years ago.
The result must be 806603.77 but why I get 806603.8 ?
float a = 855000.00f;
float b = 48396.23f;
float res = a - b;
Console.WriteLine(res);
Console.ReadKey();
You should use decimal instead because float has 32-bit with 7 digit precision only that is why the result differs, on other hand decimal has 128-bit with 28-29 digit precision.
decimal a = 855000.00M;
decimal b = 48396.23M;
decimal res = a - b;
Console.WriteLine(res);
Console.ReadKey();
Output: 806603.77
A float (also called System.Single) has a precision equivalent to approximately seven decimal figures. Your res difference needs eight significant decimal digits. Therefore it is to be expected that there is not enough precision in a float.
ADDITION:
Some extra information: Near 806,000 (806 thousand), a float only has four bits left for the fractional part. So for res it will have to choose between
806603 + 12/16 == 806603.75000000, and
806603 + 13/16 == 806603.81250000
It chooses the first one since it's closest to the ideal result. But both of these values are output as "806603.8" when calling ToString() (which Console.WriteLine(float) does call). A maximum of 7 significant decimal figures are shown with the general ToString call. To reveal that two floating-point numbers are distinct even though they print the same with the standard formatting, use the format string "R", for example
Console.WriteLine(res.ToString("R"));
Because float has limited precision (32 bits). Use double or decimal if you want more precision.
Please be aware that just blindly using Decimal isn't good enough.
Read the link posted by Oded: What Every Computer Scientist Should Know About Floating-Point Arithmetic
Only then decide on the appropriate numeric type to use.
Don't fall into the trap of thinking that just using Decimal will give you exact results; it won't always.
Consider the following code:
Decimal d1 = 1;
Decimal d2 = 101;
Decimal d3 = d1/d2;
Decimal d4 = d3*d2; // d4 = (d1/d2) * d2 = d1
if (d4 == d1)
{
Console.WriteLine("Yay!");
}
else
{
Console.WriteLine("Urk!");
}
If Decimal calculations were exact, that code should print "Yay!" because d1 should be the same as d4, right?
Well, it doesn't.
Also be aware that Decimal calculations are thousands of times slower than double calculations. They are not always suitable for non-currency calculations (e.g. calculating pixel offsets or physical things such as velocities, or anything involving transcendental numbers and so on).
I have a table with money field in my database. I have created entity and created decimal property for that money field. When the value of that field is displayed on My MVC3 view, It has four zeros 0000 after decimal like this : 5489.0000. I want to show only two 00 or decimal places. How can I fix it. Why it is showing four decimal places even I declared property as decimal.
Please suggest.
The SQL Server money datatype internally is a 64-bit integer with an implied scale of 4 decimal places. To quote Books Online, it is accurate "to ten-thousandsth of a currency unit." It is, the rough equivalent of a decimal(19,4).
The reason for the scale of 4 rather than 2 is to maintain precision in the results of arithmetic. Your ordinary currency value has a scale of 2 (e.g. $3.27) Multiplication or division of two numbers scaled to 2 decimal places gives a results that is precise to 4 decimal places: 9.23 divided by 3.27 yields a result of 2.82262996941896 (approximately). You can carry the result to whatever accuracy (number of decimal places) you desire. However, the result is only precise to 4 decimal places (2.8226) as the original values were only precise to 2 decimal places. That measurement is precise to within 1/2 of the smallest unit specified (+/- 0.005).
But I digress.
As a result of a SQL Server money value having an implied scale of 4, ADO.Net converts the value to a System.Decimal with a scale of 4. And since System.Decimal tracks scale, when you convert it to string, you get 4 decimal places.
To get fewer, you can
Round it before conversion, using the appropriate Decimal.Round() overload, or
Format it as desired (eg. (3.27M).ToString("0.00") ;.
Hope this helps.
This program:
namespace Sandbox
{
using System ;
class Program
{
static void Main( string[] args )
{
decimal pi = (decimal) Math.PI ;
string piText = pi.ToString("0.00");
Console.WriteLine("PI to 2 decimal places is {0} one way, and {1:0.00} another" , piText , pi ) ;
return;
}
}
}
Produces what you'd expect:
PI to 2 decimal places is 3.14 one way, and 3.14 another
Cheers,
N.
You have to format the string.
One thing you can do if it money you want to display is:
static void Main ()
{
decimal x = 0.999m;
decimal y = 9999999999999999999999999999m;
Console.WriteLine("My amount = {0:C}", x);
Console.WriteLine("Your amount = {0:C}", y);
}
}
OUTPUT:
Output
My amount = $1.00
Your amount = $9,999,999,999,999,999,999,999,999,999.00
the {0:C} is the currency Format
Hope this helps!
Here is everything you need to know about formatting strings.
http://blog.stevex.net/string-formatting-in-csharp/
I used this and it worked:
YourDecField.ToString("N")