¿Por qué NaN – NaN == 0.0 con Intel C++ Compiler?

3 minutos de lectura

avatar de usuario
imallet

Es bien sabido que los NaN se propagan en aritmética, pero no pude encontrar ninguna demostración, así que escribí una pequeña prueba:

#include <limits>
#include <cstdio>

int main(int argc, char* argv[]) {
    float qNaN = std::numeric_limits<float>::quiet_NaN();

    float neg = -qNaN;

    float sub1 = 6.0f - qNaN;
    float sub2 = qNaN - 6.0f;
    float sub3 = qNaN - qNaN;

    float add1 = 6.0f + qNaN;
    float add2 = qNaN + qNaN;

    float div1 = 6.0f / qNaN;
    float div2 = qNaN / 6.0f;
    float div3 = qNaN / qNaN;

    float mul1 = 6.0f * qNaN;
    float mul2 = qNaN * qNaN;

    printf(
        "neg: %f\nsub: %f %f %f\nadd: %f %f\ndiv: %f %f %f\nmul: %f %f\n",
        neg, sub1,sub2,sub3, add1,add2, div1,div2,div3, mul1,mul2
    );

    return 0;
}

El ejemplo (corriendo en vivo aquí) produce básicamente lo que esperaría (lo negativo es un poco extraño, pero tiene sentido):

neg: -nan
sub: nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan

MSVC 2015 produce algo similar. Sin embargo, Intel C++ 15 produce:

neg: -nan(ind)
sub: nan nan 0.000000
add: nan nan
div: nan nan nan
mul: nan nan

Específicamente, qNaN - qNaN == 0.0.

Esto… no puede estar bien, ¿verdad? ¿Qué dicen los estándares relevantes (ISO C, ISO C++, IEEE 754) sobre esto y por qué hay una diferencia de comportamiento entre los compiladores?

  • Javascript y Python (numpy) no tienen este comportamiento. Nan-NaN es NaN. Perl y Scala también se comportan de manera similar.

    – Pablo

    25 de agosto de 2015 a las 5:18


  • Tal vez habilitó optimizaciones matemáticas no seguras (el equivalente a -ffast-math en gcc)?

    – Mateo Italia

    25 de agosto de 2015 a las 5:21

  • @nm: No es cierto. Anexo F, que es opcional pero normativo cuando se admite, y necesario para especificar el comportamiento de coma flotante en absolutoesencialmente incorpora IEEE 754 en C.

    – R.. GitHub DEJA DE AYUDAR A ICE

    25 de agosto de 2015 a las 5:25

  • Si desea preguntar sobre el estándar IEEE 754, menciónelo en alguna parte de la pregunta.

    – norte 1.8e9-dónde-está-mi-participación m.

    25 de agosto de 2015 a las 5:27

  • Era Por supuesto esta pregunta era sobre JavaScript del título.

    – Mike G.

    25 de agosto de 2015 a las 12:51

  • Solo estaba intentando esto yo mismo. De hecho, la especificación precisa o estricta soluciona el problema.

    – imallet

    25 de agosto de 2015 a las 5:30

  • Me gustaría respaldar la decisión de Intel de usar de manera predeterminada /fp:fast: si quieres algo seguroprobablemente debería evitar que aparezcan NaN en primer lugar y, en general, no use == con números de coma flotante. Confiar en la extraña semántica que IEEE754 asigna a NaN es buscar problemas.

    – a la izquierda

    25 de agosto de 2015 a las 14:24

  • @leftaroundabout: ¿Qué encuentras raro en NaN, además de la horrible decisión en mi humilde opinión de que NaN!=NaN se volviera verdadero?

    – Super gato

    25 de agosto de 2015 a las 16:41

  • Los NaN tienen usos importantes: pueden detectar situaciones excepcionales sin necesidad de realizar pruebas después de cada cálculo. No todos los desarrolladores de punto flotante los necesitan, pero no los descarte.

    –Bruce Dawson

    25 de agosto de 2015 a las 17:03

  • @supercat Por curiosidad, ¿estás de acuerdo con la decisión de tener NaN==NaN devolver false?

    – Kyle Strand

    25 de agosto de 2015 a las 18:52

  • Fíjate que con -ffast-math, gcc ya no cumple con la norma ISO 9899:2011 con respecto a la aritmética de coma flotante.

    – fuz

    1 de septiembre de 2015 a las 11:12

  • @FUZxxl Sí, el punto es que ambas cosas los compiladores tienen un modo de punto flotante no compatible, es solo que icc tiene ese modo por defecto y gcc no.

    – zwol

    1 de septiembre de 2015 a las 22:06

  • Solo para echar leña al fuego, me gusta mucho la decisión de Intel de habilitar matemáticas rápidas de forma predeterminada. El objetivo de usar flotadores es obtener un alto rendimiento.

    – Navin

    14 de septiembre de 2015 a las 8:44


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad