# float/double unpredicted calculation results

This topic is 5396 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

We are trying to compare to floats in an ifstatement and after some debugging we traced the problem to float'ing calculation problem. The program below where compiled in Borland 5.02 but the problem where first spotted in Visual 6.0. But in Visual both the float and double calculations are wrong. We dont need more than 3-4 decimals precision but the problem are ruin the ifstatements. We wonder if there is any way to solve this problem.
int main(void) {
float fl1 = 0.0;
double db1 = 0.0;
long counter = 0;
while (counter<=4000) {
counter++;
fl1 -= 0.001f;
db1 -= 0.001;
}
printf("1%.10f", fl1);
cout << "\n";
printf("1%.10f", db1);
getch();
}

Results:
-4.0008926392
-4.0010000000



##### Share on other sites
You are simply witnessing the drawbacks of storing floating point numbers in a base 2 system. It is simply not possible to store certain floating point values in this system. There are many nice articles about this issue. Here is one.

##### Share on other sites
Welcome to the world of floating point imprecision. The internal representation of floating point numbers is only approximate. Therefore, identical operations on floats and doubles cannot be gauranteed to produce the same results, and seemingly predictable operations on either (such as adding .1 to 0 10 times) cannot be gauranteed to produce the expected results (10).

One common solution is to introduce an epsilon value into your calculations, i.e. two numbers are equal if they are within some small interval of each other. Common epsilons are .01, .001, etc., but it really depends on the scale of your application what is appropriate. Quake uses 1/32, which is actually pretty big.

In game applications, typically you just want to avoid relying on == and != operators when it comes to floats and doubles. Find ways to use <, >, <= and >= instead.

##### Share on other sites
0.1*2=0.2, 0.2*2=0.4, 0.4*2=0.8, 0.8*2=1.6, 0.6*2=1.2 and you are back to 0.2. So 0.1 in decimal is 0.0001100110011... in binary or more precisely 0.1=sum(2^(-4n)+2^(-4n-1),n,1,infinity). Generally it is best not to accumulate the errors in representation. So fll=(counter+1)/1000.0f.

##### Share on other sites
Quote:
 Original post by AskerWe are trying to compare to floats in an ifstatement and after some debugging we traced the problem to float'ing calculation problem. The program below where compiled in Borland 5.02 but the problem where first spotted in Visual 6.0. But in Visual both the float and double calculations are wrong. We dont need more than 3-4 decimals precision but the problem are ruin the ifstatements. We wonder if there is any way to solve this problem. *** Source Snippet Removed ***

Others have explained the floating point issues, so I would just like to suggest not mixing 'printf' with 'cout'. They might maintain separate buffers, and when they happen to get flushed to the screen will determain what order you actually see stuff in. That was a problem for me once, it took me a while to realize what was going on.

CM

• 13
• 18
• 29
• 11