Curiosidad: La extraña implementación de NaN

Si probáis a evaluar esta expresión: Double.NaN==Double.NaN , comprobareis con extrañeza que Java retorna false.

Sin embarco,  si realizamos la comparación con el método equals, la cosa mejora  y todo se comporta como esperábamos.

¿Por qué ocurre esto? ¿Es un Bug?

Por extraño que nos pudiera parecer no es un error en la implementación, y podemos encontrar este comportamiento en otros lenguajes orientados a objetos como C#.

La implementación del tipo double en Java se basa en el estandard «IEEE 754 Binary Floating-Point Arithmetic standard», que define que dos números con el valor NaN nunca son iguales, por lo que el operador «==» se definió de acuerdo con esta especificación. El problema surge al conciliar este comportamiento con la especificación del método equals para Object, por lo que se decidió sobrescribir el método equals de Double para adaptarlo al comportamiento de comparación de equivalencia esperado. Y aquí tenemos el conflicto «método equals» VS  «IEEE 754».

Por lo que lo recomendado es utilizar el operador cuando deseas hacer comparaciones de acuerdo con el estándar para números flotantes, y utilizar el método equals si en tu código es deseable que un NaN sea igual a un NaN.
La solución.

Si no nos queremos complicar, en la mayoría de los casos bastara con utilizar :
Double.isNaN(varNum) ;

Comentarios

  1. Hombre yo siempre había entendido que NaN no era igual ni a sí mismo, o sea aquí el equals patina un poco. Como bien dices al final todo se resume a comprobar si es un NaN con la función isNaN.

    Por cierto, a título práctico, ¿alguien ha tenido la necesidad de usar NaN alguna vez? Curiosidad…

  2. Hace unos días me encontré con una situación en la que estaba comparando sin saberlo dos NaN, ej: if(funcion(a)==funcion(a)) , donde la funcion para la variable a en algunos casos me retornaba NaN y el if me estaba volviendo loco.

Comments are closed.