1. Información general
En pocas palabras, NaN es un valor de tipo de datos numérico que significa "no es un número".
En este tutorial rápido, explicaremos el valor NaN en Java y las diversas operaciones que pueden producir o involucrar este valor.
2. ¿Qué es NaN ?
NaN suele indicar el resultado de operaciones no válidas. Por ejemplo, intentar dividir cero por cero es una de esas operaciones.
También usamos NaN para valores no representables. La raíz cuadrada de -1 es uno de esos casos, ya que podemos describir el valor ( i ) solo en números complejos.
El estándar IEEE para aritmética de coma flotante (IEEE 754) define el valor de NaN . En Java, los tipos de coma flotante flotan y doble implementan este estándar.
Java define las constantes NaN de los tipos float y double como Float .NaN y Double.NaN :
“ Una constante que tiene un valor No-Número (NaN) de tipo double. Es equivalente al valor devuelto por Double.longBitsToDouble (0x7ff8000000000000L) ”.
y:
“Una constante que contiene un valor Not-a-Number (NaN) de tipo float. Es equivalente al valor devuelto por Float.intBitsToFloat (0x7fc00000) ".
No tenemos este tipo de constantes para otros tipos de datos numéricos en Java.
3. Comparaciones con NaN
Mientras escribimos métodos en Java, debemos verificar que la entrada sea válida y esté dentro del rango esperado. El valor NaN no es una entrada válida en la mayoría de los casos. Por lo tanto, debemos verificar que el valor de entrada no sea un valor de NaN y manejar estos valores de entrada de manera apropiada.
NaN no se puede comparar con ningún valor de tipo flotante. Esto significa que obtendremos falso para todas las operaciones de comparación que involucren NaN (excepto "! =" Para el cual obtenemos verdadero ).
Obtenemos verdadero para " x! = X" si y solo si x es NaN:
System.out.println("NaN == 1 = " + (NAN == 1)); System.out.println("NaN > 1 = " + (NAN > 1)); System.out.println("NaN < 1 = " + (NAN NaN = " + (NAN > NAN)); System.out.println("NaN < NaN = " + (NAN < NAN)); System.out.println("NaN != NaN = " + (NAN != NAN));
Echemos un vistazo al resultado de ejecutar el código anterior:
NaN == 1 = false NaN > 1 = false NaN NaN = false NaN < NaN = false NaN != NaN = true
Por lo tanto, no podemos verificar el NaN comparándolo con NaN usando “==” o “! =“. De hecho, rara vez deberíamos usar operadores “==” o “! =” Con tipos flotantes o dobles .
En cambio, podemos usar la expresión “ x! = x ” . Esta expresión devuelve verdadero solo para NAN.
También podemos usar los métodos Float.isNaN y Double.isNaN para verificar estos valores . Este es el enfoque preferido ya que es más legible y comprensible:
double x = 1; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x))); x = Double.NaN; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x)));
Obtendremos el siguiente resultado al ejecutar este código:
1.0 is NaN = false 1.0 is NaN = false NaN is NaN = true NaN is NaN = true
4. Operaciones que producen NaN
Al realizar operaciones con tipos flotantes y dobles , debemos conocer los valores de NaN .
Algunos métodos y operaciones de punto flotante producen valores NaN en lugar de lanzar una excepción. Es posible que debamos manejar esos resultados de manera explícita.
Un caso común que da como resultado valores que no son números son las operaciones numéricas matemáticamente indefinidas :
double ZERO = 0; System.out.println("ZERO / ZERO = " + (ZERO / ZERO)); System.out.println("INFINITY - INFINITY = " + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY)); System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO));
Estos ejemplos dan como resultado el siguiente resultado:
ZERO / ZERO = NaN INFINITY - INFINITY = NaN INFINITY * ZERO = NaN
Las operaciones numéricas que no tienen resultados en números reales también producen NaN:
System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1)); System.out.println("LOG OF -1 = " + Math.log(-1));
Estas declaraciones resultarán en:
SQUARE ROOT OF -1 = NaN LOG OF -1 = NaN
Todas las operaciones numéricas con NaN como operando producen NaN como resultado:
System.out.println("2 + NaN = " + (2 + Double.NaN)); System.out.println("2 - NaN = " + (2 - Double.NaN)); System.out.println("2 * NaN = " + (2 * Double.NaN)); System.out.println("2 / NaN = " + (2 / Double.NaN));
Y el resultado de lo anterior es:
2 + NaN = NaN 2 - NaN = NaN 2 * NaN = NaN 2 / NaN = NaN
Finalmente, no podemos asignar nulos a variables de tipo double o float . En cambio, podemos asignar explícitamente NaN a tales variables para indicar valores perdidos o desconocidos:
double maxValue = Double.NaN;
5. Conclusión
En este artículo, discutimos NaN y las diversas operaciones que lo involucran. También discutimos la necesidad de manejar NaN mientras se realizan cálculos de punto flotante en Java de forma explícita.
El código fuente completo se puede encontrar en GitHub.