I have noticed for some strange behavior while adding two doubles, sometimes it works correct, and sometimes not!
Here is the first example:
double num1 = 0.1 + 0.7; //Guess the result?
Easy - 0.8 !!! or not?
Look at the strange result:
And guess what, the if statement is going inside the else block, and prints the num1
- and no, it doesn't prints 0.799999999999993, it prints 0.8.
So I have gone one more step forward and tried this code:
if (0.1 + 0.7 == 0.8) //Returns false ??
{
Console.WriteLine("Correct");
}
OK, strange, but now I found the correct way, it should use f (float). As I remember double has many spaces, so it can contain higher numbers, maybe this is the cause.
float num2 = 0.1f + 0.7f;
if (num2 == 0.8f) //Perfect - finally works !!!
{
Console.WriteLine("Correct");
}
else
{
Console.WriteLine(num2);
}
But now, I try this - and again it returns false, why?
if (0.1f + 0.7f == 0.8f) //Returns false :(
{
Console.WriteLine("Correct");
}
The watch results when debugging it:
Can someone explain me what's wrong here? Are those bugs?
Thanks in advance.
Floating point arithmetic is not precise. You should read the article What Every Computer Scientist Should Know About Floating-Point Arithmetic. If you want your calculations to be precise in a decimal sense, you should use the
decimal
type, where0.1m + 0.7m == 0.8m
istrue
. You should note thatdecimal
uses floating point numbers just likefloat
anddouble
, except that the base is 10, not 2. Since dealing with base 2 is so much easier and highly-optimized,decimal
is much slower. It also has its own inaccuracies, it's only precise when dealing with numbers that can be represented in a short number of decimal digits (like0.7
and0.1
), making it good for financial data.Another useful article to understand floating point numbers is Wikipedia's Double-precision floating-point format.
Call the Math.Round method to ensure that both values have the same precision. The following example modifies a previous example to use this approach so that two fractional values are equivalent:
internally, a double is stored in bits, in base-2. All integers can be represented exactly in base-2, but when it comes to fractions, it;s another matter all together.
The same way that we cannot precisely respresent the result of 1/3 in our decimal system, in a binary system you cannot represent all fractions. Since decimal is base-10, it is easy to represent x/10 in decimal, but in base-2, it is impossible for some x.
So whenever you use doubles, always be aware of some rounding errors.
For this reason, doubles are not to be used whenever exact numbers are required, as with monetary amounts.
Here is the answer: http://www.codeproject.com/Articles/383871/Demystify-Csharp-floating-point-equality-and-relat
Floating values are only approximations. To compare two floating point values you need to check the difference between them. The difference cannot be greater than
float.Epsilon
Use this to compare these values: