Bug or is it me?

Mike Bird mgb-ubuntu at yosemite.net
Sun Oct 30 03:42:25 UTC 2005


On Sat, 2005-10-29 at 19:28, Rogelio Nodal wrote:
> Hello List:
> 
>     Is this a bug?Or is it me?
> 
>     [code]
> 
>     /* Created by Anjuta version 1.2.4 */
>     /*    This file will not be overwritten */
> 
>    #include <iostream>
>    #include <fstream>
> 
>    using namespace std;
> 
>    int main()
>    {
>    
>    
>    
>     double x = 0;
>    
>    
>     x = -2.3;
>     while(x <= 2.1)
>     {
>         cout << x << endl;
>         x += 0.1;
>     }
>    
>     return (0);
>    }
>  
>     [code]
> 
> 
>     When I run this little program I get the following output:
> 
> 
>     -2.3
> -2.2
> -2.1
> -2
> -1.9
> -1.8
> -1.7
> -1.6
> -1.5
> -1.4
> -1.3
> -1.2
> -1.1
> -1
> -0.9
> -0.8
> -0.7
> -0.6
> -0.5
> -0.4
> -0.3
> -0.2
> -0.1
> 1.082e-15    ===> What the hell?
> 0.1
> 0.2
> 0.3
> 0.4
> 0.5
> 0.6
> 0.7
> 0.8
> 0.9
> 1
> 1.1
> 1.2
> 1.3
> 1.4
> 1.5
> 1.6
> 1.7
> 1.8
> 1.9
> 2       === Why did it stop here?It is supposed to stop at 2.1.
> 
> 
> 
> Thanks a lot for your time.
> 
> 
>     Rogelio.

Computers work in binary.  You can't represent 0.1 perfectly in
a normal binary float or double.  (There are special techniques
but they're beyond this discussion.)

So none of the numbers you're working with are accurate.  They're
all off by a microscopic amount.

The errors are usually so small that the print program ignores
them and just prints the nearest interesting number.  Instead of
-2.3000000000001 or -2.2999999999 it prints -2.3.  However, once
you counted down to zero, all that was left was the microscopic
error part, so the print program printed that: 1.082e-15 which
is 0.000000000000001082.

When it got to the end of the loop it had 2.1 plus a microscopic
amount.  Now 2.1 plus a microscopic amount is NOT <= 2.1, so it
stopped without printing that value near 2.1.

You really don't want to be using floats or doubles as loop
counters.  There are nasty gotchas.  If you need to print those
numbers, try something like this:

    for (int x10 = -23; x10 <= 21; ++x10)
	cout << (x10 * 0.1) << endl;	

--Mike Bird





More information about the ubuntu-users mailing list