Si se pregunta "¿de qué sirve NaN?" en Java (o cualquier otro lenguaje), puedo darle un caso de uso donde es muy útil: cuando tengo una matriz 2-D de flotadores, pero mi cálculo no tiene un valor significativo para alguna parte de esa matriz 2-D, Completaré ese valor con "NaN". Esto se puede usar para indicar a los usuarios posteriores de mi cálculo (como cuando se convierte en una imagen rasterizada) "no presten atención al valor en este punto". ¡Muy útil!
Dan H
Por cierto, ¿qué, exactamente, significa "encoger" un doble? Curioso ...
"NaN" significa "no es un número". "Nan" se produce si una operación de coma flotante tiene algunos parámetros de entrada que hacen que la operación produzca algún resultado indefinido. Por ejemplo, 0.0 dividido por 0.0 es aritméticamente indefinido. Sacar la raíz cuadrada de un número negativo tampoco está definido.
Además, NaN está definido por el estándar IEEE para aritmética de punto flotante (IEEE 754) de manera bastante explícita, que Java sigue ciegamente. Leer el estándar le abre los ojos a muchas cosas, y los valores múltiples de cero son una de las cosas.
Esko
37
Además, NaNtiene la interesante propiedad de ser el único "número" que no es igual a sí mismo cuando se compara. Por lo tanto, una prueba común (y en muchos idiomas la única) si un número xes NaNes la siguiente:boolean isNaN(x){return x != x;}
quazgar
3
¿Link en respuesta está muerto?
Pang
3
... "Sacar la raíz cuadrada de un número negativo no está definido (en aritmética)" ... ¡No lo es! es en realidad iy algunos lenguajes como Python lo manejan muy bien ... Puede que no sea el caso en javati
Rafael T
5
@RafaelT Yo diría que no está definido en aritmética no compleja. No hay forma de asignar un número complejo a un flotante o doble en Java. Python se escribe dinámicamente, por lo que es posible que solo devuelva un número complejo en este caso.
sstn
19
NaNsignifica "No es un número" y es básicamente una representación de un valor de punto flotante especial en el estándar de punto flotante IEE 754 . NaN generalmente significa que el valor es algo que no se puede expresar con un número de punto flotante válido.
Una conversión dará como resultado este valor, cuando el valor que se convierte es otra cosa, por ejemplo, al convertir una cadena que no representa un número.
¿Conversión de cómo? ¿Con parseFloat()o parseDouble? ¿O algo mas?
Alonso del Arte
14
NaNsignifica "No es un número" y es el resultado de operaciones indefinidas en números de punto flotante como, por ejemplo, dividir cero por cero. (Tenga en cuenta que aunque dividir un número distinto de cero por cero también suele ser indefinido en matemáticas, no da como resultado NaN sino un infinito positivo o negativo).
NaNsignifica "No es un número". Es un valor de punto flotante especial que significa que el resultado de una operación no se definió o no se puede representar como un número real.
Consulte aquí para obtener más explicaciones de este valor.
Lo primero que debes saber es que el concepto de NaN se implementa directamente en el hardware de la CPU.
Todas las principales CPU modernas parecen seguir IEEE 754, que especifica formatos de punto flotante, y los NaN, que son solo valores flotantes especiales, son parte de ese estándar.
Por lo tanto, el concepto será muy similar en cualquier lenguaje, incluido Java, que solo emite código de punto flotante directamente a la CPU.
Antes de continuar, es posible que desee leer primero las siguientes respuestas que he escrito:
Ahora para alguna acción de Java. La mayoría de las funciones de interés que no se encuentran en el idioma principal viven en el interior java.lang.Float.
Nan.java
import java.lang.Float;import java.lang.Math;publicclassNan{publicstaticvoid main(String[] args){// Generate some NaNs.float nan =Float.NaN;float zero_div_zero =0.0f/0.0f;float sqrt_negative =(float)Math.sqrt(-1.0);float log_negative =(float)Math.log(-1.0);float inf_minus_inf =Float.POSITIVE_INFINITY -Float.POSITIVE_INFINITY;float inf_times_zero =Float.POSITIVE_INFINITY *0.0f;float quiet_nan1 =Float.intBitsToFloat(0x7fc00001);float quiet_nan2 =Float.intBitsToFloat(0x7fc00002);float signaling_nan1 =Float.intBitsToFloat(0x7fa00001);float signaling_nan2 =Float.intBitsToFloat(0x7fa00002);float nan_minus =-nan;// Generate some infinities.float positive_inf =Float.POSITIVE_INFINITY;float negative_inf =Float.NEGATIVE_INFINITY;float one_div_zero =1.0f/0.0f;float log_zero =(float)Math.log(0.0);// Double check that they are actually NaNs.assertFloat.isNaN(nan);assertFloat.isNaN(zero_div_zero);assertFloat.isNaN(sqrt_negative);assertFloat.isNaN(inf_minus_inf);assertFloat.isNaN(inf_times_zero);assertFloat.isNaN(quiet_nan1);assertFloat.isNaN(quiet_nan2);assertFloat.isNaN(signaling_nan1);assertFloat.isNaN(signaling_nan2);assertFloat.isNaN(nan_minus);assertFloat.isNaN(log_negative);// Double check that they are infinities.assertFloat.isInfinite(positive_inf);assertFloat.isInfinite(negative_inf);assert!Float.isNaN(positive_inf);assert!Float.isNaN(negative_inf);assert one_div_zero == positive_inf;assert log_zero == negative_inf;// Double check infinities.// See what they look like.System.out.printf("nan 0x%08x %f\n",Float.floatToRawIntBits(nan ), nan );System.out.printf("zero_div_zero 0x%08x %f\n",Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );System.out.printf("sqrt_negative 0x%08x %f\n",Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );System.out.printf("log_negative 0x%08x %f\n",Float.floatToRawIntBits(log_negative ), log_negative );System.out.printf("inf_minus_inf 0x%08x %f\n",Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );System.out.printf("inf_times_zero 0x%08x %f\n",Float.floatToRawIntBits(inf_times_zero), inf_times_zero);System.out.printf("quiet_nan1 0x%08x %f\n",Float.floatToRawIntBits(quiet_nan1 ), quiet_nan1 );System.out.printf("quiet_nan2 0x%08x %f\n",Float.floatToRawIntBits(quiet_nan2 ), quiet_nan2 );System.out.printf("signaling_nan1 0x%08x %f\n",Float.floatToRawIntBits(signaling_nan1), signaling_nan1);System.out.printf("signaling_nan2 0x%08x %f\n",Float.floatToRawIntBits(signaling_nan2), signaling_nan2);System.out.printf("nan_minus 0x%08x %f\n",Float.floatToRawIntBits(nan_minus ), nan_minus );System.out.printf("positive_inf 0x%08x %f\n",Float.floatToRawIntBits(positive_inf ), positive_inf );System.out.printf("negative_inf 0x%08x %f\n",Float.floatToRawIntBits(negative_inf ), negative_inf );System.out.printf("one_div_zero 0x%08x %f\n",Float.floatToRawIntBits(one_div_zero ), one_div_zero );System.out.printf("log_zero 0x%08x %f\n",Float.floatToRawIntBits(log_zero ), log_zero );// NaN comparisons always fail.// Therefore, all tests that we will do afterwards will be just isNaN.assert!(1.0f< nan);assert!(1.0f== nan);assert!(1.0f> nan);assert!(nan == nan);// NaN propagate through most operations.assertFloat.isNaN(nan +1.0f);assertFloat.isNaN(1.0f+ nan);assertFloat.isNaN(nan + nan);assertFloat.isNaN(nan /1.0f);assertFloat.isNaN(1.0f/ nan);assertFloat.isNaN((float)Math.sqrt((double)nan));}}
No es un tipo de Java, pero en JS y otros lenguajes que uso es "No es un número", lo que significa que alguna operación hizo que no se convirtiera en un número válido.
Discuto con esta respuesta. Primero: "NaN" ES un valor válido para un flotante IEEE. (Después de todo, está definido en la especificación ... entonces es "válido", ¿verdad?). Segundo: la "división por cero" se puede representar mediante IEEE "Infinito positivo" o "Infinito negativo"; un mejor ejemplo de "NaN" es "cero dividido por cero", como algunas otras respuestas han señalado correctamente.
Dan H
"Valor válido" y "definido en especificaciones" no es lo mismo. Aceptado 0/0.
Respuestas:
Tomado de esta página :
fuente
NaN
tiene la interesante propiedad de ser el único "número" que no es igual a sí mismo cuando se compara. Por lo tanto, una prueba común (y en muchos idiomas la única) si un númerox
esNaN
es la siguiente:boolean isNaN(x){return x != x;}
i
y algunos lenguajes como Python lo manejan muy bien ... Puede que no sea el caso enjava
tiNaN
significa "No es un número" y es básicamente una representación de un valor de punto flotante especial en el estándar de punto flotante IEE 754 . NaN generalmente significa que el valor es algo que no se puede expresar con un número de punto flotante válido.Una conversión dará como resultado este valor, cuando el valor que se convierte es otra cosa, por ejemplo, al convertir una cadena que no representa un número.
fuente
parseFloat()
oparseDouble
? ¿O algo mas?NaN
significa "No es un número" y es el resultado de operaciones indefinidas en números de punto flotante como, por ejemplo, dividir cero por cero. (Tenga en cuenta que aunque dividir un número distinto de cero por cero también suele ser indefinido en matemáticas, no da como resultado NaN sino un infinito positivo o negativo).fuente
NaN
significa "No es un número". Es un valor de punto flotante especial que significa que el resultado de una operación no se definió o no se puede representar como un número real.Consulte aquí para obtener más explicaciones de este valor.
fuente
NaN son las siglas de Not a Number. Se utiliza para indicar cualquier valor matemáticamente indefinido. Como dividir 0.0 por 0.0. Puede buscar aquí para obtener más información: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm
Publique su programa aquí si necesita más ayuda.
fuente
NaN = No es un número.
fuente
No significa un número. Es una representación común de un valor numérico imposible en muchos lenguajes de programación.
fuente
Ejemplo ejecutable mínimo
Lo primero que debes saber es que el concepto de NaN se implementa directamente en el hardware de la CPU.
Todas las principales CPU modernas parecen seguir IEEE 754, que especifica formatos de punto flotante, y los NaN, que son solo valores flotantes especiales, son parte de ese estándar.
Por lo tanto, el concepto será muy similar en cualquier lenguaje, incluido Java, que solo emite código de punto flotante directamente a la CPU.
Antes de continuar, es posible que desee leer primero las siguientes respuestas que he escrito:
Ahora para alguna acción de Java. La mayoría de las funciones de interés que no se encuentran en el idioma principal viven en el interior
java.lang.Float
.Nan.java
GitHub aguas arriba .
Corre con:
Salida:
Entonces de esto aprendemos algunas cosas:
operaciones flotantes extrañas que no tienen ningún resultado sensible dan NaN:
0.0f / 0.0f
sqrt(-1.0f)
log(-1.0f)
generar un
NaN
.En C, en realidad es posible solicitar que se generen señales en tales operaciones
feenableexcept
para detectarlas, pero no creo que esté expuesto en Java: ¿Por qué la división de enteros por cero 1/0 da error pero punto flotante 1 / 0.0 devuelve "Inf"?operaciones extrañas que están en el límite de más o menos infinito, sin embargo, dan + - infinito en lugar de NaN
1.0f / 0.0f
log(0.0f)
0.0
casi cae en esta categoría, pero probablemente el problema es que podría ir a más o menos infinito, por lo que se dejó como NaN.si NaN es la entrada de una operación flotante, la salida también tiende a ser NaN
hay varios valores posibles de NaN
0x7fc00000
,0x7fc00001
,0x7fc00002
, aunque x86_64 parece generar solamente0x7fc00000
.NaN e infinito tienen una representación binaria similar.
Analicemos algunos de ellos:
A partir de esto confirmamos lo que especifica IEEE754:
Los NaN pueden ser positivos o negativos (bit superior), aunque esto no tiene ningún efecto en las operaciones normales.
Probado en Ubuntu 18.10 amd64, OpenJDK 1.8.0_191.
fuente
No es un tipo de Java, pero en JS y otros lenguajes que uso es "No es un número", lo que significa que alguna operación hizo que no se convirtiera en un número válido.
fuente
Literalmente significa "No es un número". Sospecho que algo anda mal con su proceso de conversión.
Consulte la sección No es un número en esta referencia
fuente
No es un valor de punto flotante válido (por ejemplo, el resultado de la división por cero)
http://en.wikipedia.org/wiki/NaN
fuente