Tengo un programa que intenta reducir double
a un número deseado. El resultado que obtengo es NaN
.
¿Qué NaN
significa en Java?
Tengo un programa que intenta reducir double
a un número deseado. El resultado que obtengo es NaN
.
¿Qué NaN
significa en Java?
Respuestas:
Tomado de esta página :
"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.
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úmero x
es NaN
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 en java
ti
NaN
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.
parseFloat()
o parseDouble
? ¿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).
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.
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.
NaN = No es un número.
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
import java.lang.Float;
import java.lang.Math;
public class Nan {
public static void 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.
assert Float.isNaN(nan);
assert Float.isNaN(zero_div_zero);
assert Float.isNaN(sqrt_negative);
assert Float.isNaN(inf_minus_inf);
assert Float.isNaN(inf_times_zero);
assert Float.isNaN(quiet_nan1);
assert Float.isNaN(quiet_nan2);
assert Float.isNaN(signaling_nan1);
assert Float.isNaN(signaling_nan2);
assert Float.isNaN(nan_minus);
assert Float.isNaN(log_negative);
// Double check that they are infinities.
assert Float.isInfinite(positive_inf);
assert Float.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.
assert Float.isNaN(nan + 1.0f);
assert Float.isNaN(1.0f + nan);
assert Float.isNaN(nan + nan);
assert Float.isNaN(nan / 1.0f);
assert Float.isNaN(1.0f / nan);
assert Float.isNaN((float)Math.sqrt((double)nan));
}
}
Corre con:
javac Nan.java && java -ea Nan
Salida:
nan 0x7fc00000 NaN
zero_div_zero 0x7fc00000 NaN
sqrt_negative 0xffc00000 NaN
log_negative 0xffc00000 NaN
inf_minus_inf 0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1 0x7fc00001 NaN
quiet_nan2 0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus 0xffc00000 NaN
positive_inf 0x7f800000 Infinity
negative_inf 0xff800000 -Infinity
one_div_zero 0x7f800000 Infinity
log_zero 0xff800000 -Infinity
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 solamente 0x7fc00000
.
NaN e infinito tienen una representación binaria similar.
Analicemos algunos de ellos:
nan = 0x7fc00000 = 0 11111111 10000000000000000000000
positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
| | |
| | mantissa
| exponent
|
sign
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.
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.
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
No es un valor de punto flotante válido (por ejemplo, el resultado de la división por cero)