Jump to content
  • Advertisement
Sign in to follow this  
Asker

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Asker
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.

*** 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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!