Optimizaciones CLR JIT viola la causalidad?
Estaba escribiendo un ejemplo instructivo para un colega para mostrarle por qué probar flotadores para la igualdad a menudo es una mala idea. El ejemplo que utilicé fue agregar .1 diez veces y comparar con 1.0 (el que se me mostró en mi clase introductoria numérica). Me sorprendió descubrir que los dos resultadoseran iguales (código + salida)
float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
@float += 0.1f;
}
Console.WriteLine(@float == 1.0f);
Algunas investigaciones mostraron que no se podía confiar en este resultado (al igual que la igualdad de flotación). Lo que más me sorprendió fue agregar códigodespués el otro código podría cambiar el resultado del cálculo (código + salida) Tenga en cuenta que este ejemplo tiene exactamente el mismo código e IL, con una línea más de C # añadida.
float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
@float += 0.1f;
}
Console.WriteLine(@float == 1.0f);
Console.WriteLine(@float.ToString("G9"));
Sé que se supone que no debo usar la igualdad en las carrozas y, por lo tanto, no debería importarme demasiado esto, pero me pareció bastante sorprendente, al igual que a todos los que le he mostrado esto. Haciendo cosasdespués ha realizado un cálculo cambia el valor del cálculo anterior? No creo que ese sea el modelo de computación que la gente suele tener en mente.
No estoy totalmente perplejo, parece seguro asumir que se está produciendo algún tipo de optimización en el caso "igual" que cambia el resultado del cálculo (construir en modo de depuración evita el caso "igual"). Aparentemente, la optimización se abandona cuando el CLR descubre que más tarde necesitará encajonar el flotador.
He buscado un poco, pero no pude encontrar una razón para este comportamiento. Alguien me podria explicar?