Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this loop never end? [duplicate]

Possible Duplicate:
problem in comparing double values in C#

I've read it elsewhere, but really forget the answer so I ask here again. This loop seems never end regardless you code it in any language (I test it in C#, C++, Java...):

double d = 2.0;
while(d != 0.0){
   d = d - 0.2;
}
like image 232
Truong Ha Avatar asked Jul 28 '10 08:07

Truong Ha


2 Answers

Floating point calculations are not perfectly precise. You will get a representation error because 0.2 doesn't have an exact representation as a binary floating point number so the value doesn't become exactly equal to zero. Try adding a debug statement to see the problem:

double d = 2.0;
while (d != 0.0)
{
    Console.WriteLine(d);
    d = d - 0.2;
}
2
1,8
1,6
1,4
1,2
1
0,8
0,6
0,4
0,2
2,77555756156289E-16   // Not exactly zero!!
-0,2
-0,4

One way to solve it is to use the type decimal.

like image 166
Mark Byers Avatar answered Oct 26 '22 07:10

Mark Byers


(For one thing you're not using the same variable throughout, but I'll assume that's a typo :)

0.2 isn't really 0.2. It's the closest double value to 0.2. When you've subtracted that 10 times from 2.0, you won't end up with exactly 0.0.

In C# you can change to use the decimal type instead, which will work:

// Works
decimal d = 2.0m;
while (d != 0.0m) {
   d = d - 0.2m;
}

This works because the decimal type does represent decimal values like 0.2 precisely (within limits; it's a 128-bit type). Every value involved is precisely representable, so it works. What wouldn't work would be this:

decimal d = 2.0m;
while (d != 0.0m) {
   d = d - 1m/3m;
}

Here, "a third" isn't exactly representable so we end up with the same problem as before.

In general though, it's a bad idea to perform exact equality comparisons between floating point numbers - usually you compare them within a certain tolerance.

I have articles on floating binary point and floating decimal point from a C#/.NET context, which explain things in more detail.

like image 34
Jon Skeet Avatar answered Oct 26 '22 05:10

Jon Skeet