0

Possible Duplicate:
Dealing with accuracy problems in floating-point numbers

I am writing an OpenGl animation and am using a float variable "time" to keep track of the time. I am incrementing the "time" variable by 0.01 .I have certain conditions to fulfil whenever "time" reaches an integer value.The issue is that after a certain time the float increment shows weird behavior. I start from time = 0 and I see that after "time" reaches 0.83 the next value is 0.839999. I though this could be related to float precision so I tried using double/long double and I found that instead of reaching the value 1.00 the code is reaching the value 1.0000007.

I tried incrementing by "0.01f" instead of "0.01" but got no success. Is this some bug in Visual Studio or am I doing it the wrong way? I could post the code but I don't think it's of much use as I am assigning to "time" just at one place and it's just being used at other places.

Community
  • 1
  • 1
code4fun
  • 2,661
  • 9
  • 25
  • 39
  • It's not a bug in the compiler. In fact, whenever you're looking at some odd behavior in your program and the thought occurs to you, "I wonder if this is a bug in the compiler," you can rest assured that the answer is never (as near to never as it doesnt matter) "yes" Accpeting this will make you a happier and more productive programmer. – John Dibling Dec 04 '12 at 14:52

3 Answers3

4

Don't ever compare floating point values for equality unless you know exactly what you are doing. I would strongly suggest you use integers (perhaps integer numbers of milliseconds) for this purpose.

See What Every Computer Scientist Should Know About Floating-Point Arithmetic for more information.

Floating point is a fixed-precision format. This is an inherent limitation of fixed-precision formats.

For example, say you used six decimal digits of precision. One-third would be .333333. But if you add one-third three times, you get .999999, not 1. That's the nature of the beast.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
2

Not exactly recommending this, but the issue is that the 0.1 cannot be represented exactly as double. 1.0 can be. So if you make your time-step a (negative) power of two, you will find a difference. By way of illustration:

    double delta = 1.0 / 8;
    int stopper = 10;
    int nextInt = 1;
    for (double t = 0; t <= stopper; t += delta)
    {
        if (t == nextInt)
        {
            std::cout << "int ";
            ++nextInt;
        }
        else 
            std::cout << "    ";
        std::cout << t << std::endl;
    }
Keith
  • 6,756
  • 19
  • 23
1

Just round "time" after each increment to make sure it maintains a sensible value.

Something like that:

double round(double value, double precision)
{
    return floor(value / precision + 0.5) * precision;
}
time = round(time + 0.1, 0.1);
spyder
  • 470
  • 10
  • 22