Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Getting strange results for a simple math operations

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:

enter image description here

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:

enter image description here

Can someone explain me what's wrong here? Are those bugs?

Thanks in advance.

like image 529
Misha Zaslavsky Avatar asked Oct 26 '13 12:10

Misha Zaslavsky


2 Answers

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, where 0.1m + 0.7m == 0.8m is true. You should note that decimal uses floating point numbers just like float and double, 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 (like 0.7 and 0.1), making it good for financial data.

Another useful article to understand floating point numbers is Wikipedia's Double-precision floating-point format.

like image 51
Tim S. Avatar answered Sep 25 '22 16:09

Tim S.


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.

like image 44
oerkelens Avatar answered Sep 23 '22 16:09

oerkelens