valores uso sobrecargar sobrecarga retorno programacion operator operadores operador clases c++ c nan ieee-754

uso - ¿Qué haría que los operadores C/C++<,<= y== devuelvan verdadero si cualquiera de los argumentos es NaN?



valores de retorno en c (1)

Mi comprensión de las reglas de las comparaciones de punto flotante IEEE-754 es que todos los operadores de comparación excepto != Devolverán false si alguno de los dos argumentos es NaN, mientras que el operador != Devolverá verdadero. Puedo reproducir fácilmente este comportamiento con una simple prueba independiente:

for (int ii = 0; ii < 4; ++ii) { float a = (ii & 1) != 0 ? NAN : 1.0f; float b = (ii & 2) != 0 ? NAN : 2.0f; #define TEST(OP) printf("%4.1f %2s %4.1f => %s/n", a, #OP, b, a OP b ? "true" : "false"); TEST(<) TEST(>) TEST(<=) TEST(>=) TEST(==) TEST(!=) }

Esto imprime los resultados esperados: (NaN está formateado como -1.$ En el tiempo de ejecución de MSVC)

1.0 < 2.0 => true 1.0 > 2.0 => false 1.0 <= 2.0 => true 1.0 >= 2.0 => false 1.0 == 2.0 => false 1.0 != 2.0 => true -1.$ < 2.0 => false -1.$ > 2.0 => false -1.$ <= 2.0 => false -1.$ >= 2.0 => false -1.$ == 2.0 => false -1.$ != 2.0 => true 1.0 < -1.$ => false 1.0 > -1.$ => false 1.0 <= -1.$ => false 1.0 >= -1.$ => false 1.0 == -1.$ => false 1.0 != -1.$ => true -1.$ < -1.$ => false -1.$ > -1.$ => false -1.$ <= -1.$ => false -1.$ >= -1.$ => false -1.$ == -1.$ => false -1.$ != -1.$ => true

Sin embargo, cuando pego este fragmento de código en las profundidades de los bucles internos de mi aplicación, donde se realizan todos los cálculos de punto flotante, obtengo estos resultados inexplicables:

1.0 < 2.0 => true 1.0 > 2.0 => false 1.0 <= 2.0 => true 1.0 >= 2.0 => false 1.0 == 2.0 => false 1.0 != 2.0 => true -1.$ < 2.0 => true -1.$ > 2.0 => false -1.$ <= 2.0 => true -1.$ >= 2.0 => false -1.$ == 2.0 => true -1.$ != 2.0 => false 1.0 < -1.$ => true 1.0 > -1.$ => false 1.0 <= -1.$ => true 1.0 >= -1.$ => false 1.0 == -1.$ => true 1.0 != -1.$ => false -1.$ < -1.$ => true -1.$ > -1.$ => false -1.$ <= -1.$ => true -1.$ >= -1.$ => false -1.$ == -1.$ => true -1.$ != -1.$ => false

Por alguna razón, los operadores < , <= y == devuelven inesperadamente verdadero cuando uno o ambos argumentos son NaN. Además, el operador != Inesperadamente devuelve falso.

Este es un código de 64 bits, construido con Visual Studio 2010, que se ejecuta en un Intel Xeon E5-2650. Al usar _mm_getcsr() , confirmé que el registro de CSR tiene el mismo valor en ambos escenarios.

¿Qué más podría influir en el comportamiento de las matemáticas de punto flotante como esta?


Este comportamiento se debe a la opción del compilador MSVC /fp:fast , que (entre otras cosas) le permite al compilador realizar comparaciones sin tener en cuenta el comportamiento correcto de NaN en un esfuerzo por generar un código más rápido. Usar /fp:fast o /fp:fast lugar hace que estas comparaciones se comporten como se espera cuando se presentan argumentos de NaN.