Visual Studio 2010 que muestra un comportamiento extraño en flotación/incremento doble [duplicado]

Posible duplicado:
Manejo de problemas de precisión en números de punto flotante

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.

preguntado el 04 de diciembre de 12 a las 04:12

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

3 Respuestas

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

Vea Lo que todo informático debe saber sobre la aritmética de coma flotante , para obtener más información.

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.

Respondido el 04 de diciembre de 12 a las 04:12

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;
    }

Respondido el 04 de diciembre de 12 a las 04:12

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

Algo como eso:

double round(double value, double precision)
{
    return floor(value / precision + 0.5) * precision;
}
time = round(time + 0.1, 0.1);

Respondido el 04 de diciembre de 12 a las 04:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.