Click here to Skip to main content
15,888,301 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hello,
Take a look at this C#'s code:
C#
double f = 10.123 - 10.0;
Console.WriteLine(f);

The result must be '0.123', but here it is '0.122999999999999'!!
What's the problem??
I know that the difference is Epsilon, but what if I would like the real result?

Thank's in advance!
Posted
Updated 25-Mar-19 8:40am

You cannot have the real result: "What Every Computer Scientist Should Know About Floating-Point Arithmetic"[^].

As workaround you might use the rounding provided on output representation:
C#
double f = 10.123 - 10.0;
Console.WriteLine(f.ToString("0.###"));
 
Share this answer
 
Comments
Kornfeld Eliyahu Peter 5-Oct-14 5:23am    
Or maybe using decimal can help OP...
This is a inherent property of floating-point computer arithmetic, i.e. arithmetic with limited precision.

As example, take the number 1/7 = 0.142857142857142857142857...
If you now calculate 7x(1/7) with limited precision (e.g. with paper and pencil) you see the same effect:

precision1/77x(1/7)rounding to 2 digits
0000.00
10.10.70.70
20.140.980.98
30.1420.9940.99
40.14280.99961.00
50.142850.999951.00
60.1428570.9999991.00
.........
120.1428571428570.9999999999991.00
............


Analogous with computer arithmetic, you have to take care of exactly this issue.
You have to consider three issues if working with floating point numbers:

  1. Decide on a precision for displaying numbers (e.g. a physical length given in meters [m] and precise to 1 millimeter [mm] --> display precision = 3 --> rounding to 3 fraction digits while displaying). E.g. d.ToString("F3").
  2. Decide on a comparison delta used for equality and relation operations (like ==, !=, <, <=, >=, >). E.g. display precision + 1 --> see Demystify C# floating-point equality and relation operations[^]. E.g. var epsilon = new RealExtension.Epsilon(1E-4);...if (x.EQ(y, epsilon)) ...
  3. Do not use GetHashCode() on floating point numbers, neither directly nor indirectly e.g. as key in dictionaries and hash collections (due to the not precise nature of the floating point numbers).


Cheers
Andi

PS: Do not cast forth and back between number domains. This is a bad habit that cost you more in the long run than it helps. Decide on a domain and stay in it. Single has the same problem as stated above, it is simply shifted to other places.
 
Share this answer
 
Comments
BillWoodruff 5-Oct-14 5:54am    
+5 very comprehensive answer.
Andreas Gieriet 5-Oct-14 6:03am    
Thanks for your 5!
Cheers
Andi
MSDN:
Single values have less precision than Double values. A Single value that is converted to a seemingly equivalent Double often does not equal the Double value because of differences in precision. In the following example, the result of identical division operations is assigned to a Double and a Single value. After the Single value is cast to a Double, a comparison of the two values shows that they are unequal.

http://msdn.microsoft.com/en-us/library/system.double.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-7[^]

When you write the line
C#
double f = 10.123 - 10.0;

it is the same as to write
C#
double f = 10.123d - 10.0d;

as C# default is to double precision floating point...
There is no way to get the exact value but you can get closer (or further) to it...All you have to do is to decide what the precision you need...
for example by changing your line to
C#
double f = 10.123f - 10.0f

you will get the result of 0.12300014495849609...
As you can see at the bottom line you will have to play with rounding up/down while using floating point numbers...

However you are fortunate - this problem of floating points was known to Microsoft and there is an other type that can be used for floating point computations - decimal[^]...
It has it drawbacks (read the MSDN page) but for your range (according to your case) it will give the correct answer. Try...
C#
decimal f = 10.123m - 10.0m;
 
Share this answer
 
v2
Comments
BillWoodruff 5-Oct-14 5:53am    
+5 clear, accurate, and shows a technique that solves the problem. Whoever voted this a #1 should have their head examined.
Kornfeld Eliyahu Peter 5-Oct-14 5:57am    
Thank you!
(In fact I posted it in two steps - some technical problems - and the first version contained only the MSDN quote...So that can explain a lot...)
Yes this is the common bug for converting single to double
to avoid it do one of the this:
convert number to double
get result in single
convert single to string then convert them to double

C#
single f = 10.123 - 10.0;
 
Share this answer
 
v2
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900