Estaba estudiando preguntas de OCPJP y encontré este código extraño:
public static void main(String a[]) {
System.out.println(Double.NaN==Double.NaN);
System.out.println(Double.NaN!=Double.NaN);
}
Cuando ejecuté el código, obtuve:
false
true
¿Cómo es la salida falsecuando estamos comparando dos cosas que se parecen entre sí? Que NaNsignifica

In [1]: NaN==NaN Out[1]: FalseDouble.NaN==Double.NaNdebería volver verdadero siDouble.NaNfueran de tipojava.lang.Double. Sin embargo, su tipo es el primitivodouble, y las reglas del operador paradoubleaplicar (que exigen esta desigualdad para cumplir con IEEE 754, como se explica en las respuestas).Respuestas:
NaN significa "No es un número".
Java Language Specification (JLS) Third Edition dice :
fuente
false. Entonces, ese estándar difiere de Java en que IEEE lo exige(NAN != NAN) == false.NaN no es, por definición, igual a ningún número, incluido NaN. Esto es parte del estándar IEEE 754 e implementado por la CPU / FPU. No es algo a lo que la JVM tenga que agregar ninguna lógica para soportar.
http://en.wikipedia.org/wiki/NaN
Java trata todo NaN como NaN silencioso.
fuente
¿Por qué esa lógica?
NaNsignificaNot a Number. ¿Qué no es un número? Cualquier cosa. Puede tener cualquier cosa en un lado y cualquier cosa en el otro lado, por lo que nada garantiza que ambos sean iguales.NaNse calcula conDouble.longBitsToDouble(0x7ff8000000000000L)y como puede ver en la documentación delongBitsToDouble:Además,
NaNse trata lógicamente dentro de la API.Documentación
Por cierto,
NaNse prueba como muestra de código:Solución
Lo que puedes hacer es usar
compare/compareTo:O
equals:fuente
NaN != NaNser falso haría que los programas sean más complicados queNaN != NaNser cierto? Sé que IEEE tomó la decisión hace mucho tiempo, pero desde una perspectiva práctica, nunca he visto casos en los que sea útil. Si se supone que una operación se ejecuta hasta que las iteraciones consecutivas produzcan el mismo resultado, tener dos iteraciones consecutivas produce NaN se detectaría "naturalmente" como una condición de salida si no fuera por ese comportamiento.f(f(f...f(x))), y encuentra unoy=f[n](x)para algunos de losncuales el resultado def(y)es indistinguibley, entoncesyserá indistinguible del resultado de cualquier anidamiento más profundof(f(f(...f(y))). Incluso si uno quisieraNaN==NaNser falso, tenerloNan!=Nantambién sería menos "sorprendente" quex!=xser cierto para algunas x.Double.NaNno lo esDouble, perodoublela pregunta está relacionada con el comportamiento dedouble. Aunque existen funciones que pueden evaluar una relación de equivalencia que involucradoublevalores, la única respuesta convincente que conozco para "por qué" (que es parte de la pregunta original) es "porque algunas personas en el IEEE no pensaron que la prueba de igualdad debería definir una relación de equivalencia ". Por cierto, ¿hay alguna forma idiomática concisa de probarxyypara la equivalencia usando solo operadores primitivos? Todas las formulaciones que conozco son bastante torpes.Puede que no sea una respuesta directa a la pregunta. Pero si desea verificar si algo es igual a esto
Double.NaN, debe usar esto:Esto volverá
truefuente
El javadoc para Double.NaN lo dice todo:
Curiosamente, la fuente de
DoubledefineNaNasí:El comportamiento especial que describe está conectado a la JVM.
fuente
según, el estándar IEEE para aritmética de coma flotante para números de doble precisión,
Lo que significa,
Si todos los
Ebits son 1, y si hay algún bit distinto de cero,Fentonces el número esNaN.por lo tanto, entre otros, todos los siguientes números son
NaN,En particular, no puedes probar
para verificar si un resultado particular es igual
Double.NaN, porque todos los valores "no un número" se consideran distintos. Sin embargo, puede usar elDouble.isNaNmétodo:fuente
NaN es un valor especial que denota "no un número"; es el resultado de ciertas operaciones aritméticas no válidas, como
sqrt(-1), y tiene la propiedad (a veces molesta) queNaN != NaN.fuente
Ningún número representa el resultado de operaciones cuyo resultado no es representable con un número. La operación más famosa es 0/0, cuyo resultado no se conoce.
Por esta razón, NaN no es igual a nada (incluidos otros valores que no sean un número). Para obtener más información, solo consulte la página de Wikipedia: http://en.wikipedia.org/wiki/NaN
fuente
0/0.0/0siempre es NaN, pero NaN puede ser el resultado de otras operaciones, como2+NaN:an operation that has no mathematically definite result produces NaNsegún la respuesta de @AdrianMitevSegún este enlace , tiene varias situaciones y es difícil de recordar. Así es como los recuerdo y los distingo.
NaNsignifica "matemáticamente indefinido", por ejemplo: "el resultado de 0 dividido por 0 es indefinido" y porque es indefinido, entonces "la comparación relacionada con indefinido es, por supuesto, indefinida". Además, funciona más como premisas matemáticas. Por otro lado, tanto el infinito positivo como el negativo están predefinidos y son definitivos, por ejemplo, "infinito positivo o negativo grande está bien definido matemáticamente".fuente