2010-01-28 18 views
8

El documentation for java.lang.Double.NaN dice que es¿Cuáles son los otros valores de NaN?

Una celebración de un valor constante no-a-Number (NaN) de tipo double. Es equivalente al valor devuelto por Double.longBitsToDouble(0x7ff8000000000000L).

Esto parece implicar que hay otros. Si es así, ¿cómo puedo obtenerlos, y esto puede hacerse de forma portátil?

Para que quede claro, me gustaría encontrar los valores de doublex tal que

Double.doubleToRawLongBits(x) != Double.doubleToRawLongBits(Double.NaN) 

y

Double.isNaN(x) 

son ambas verdaderas.

+0

¿Quiere decir hay otra 'java.lang * NaN'..? –

+0

@Dominic: No, he agregado lo que creo que es una aclaración a la pregunta. –

Respuesta

8

Necesita doubleToRawLongBits en lugar de doubleToLongBits.

doubleToRawLongBits extrae la representación binaria real. doubleToLongBits no, convierte todos los NaN s al predeterminado NaN primero.

double n = Double.longBitsToDouble(0x7ff8000000000000L); // default NaN 
double n2 = Double.longBitsToDouble(0x7ff8000000000100L); // also a NaN, but M != 0 

System.out.printf("%X\n", Double.doubleToLongBits(n)); 
System.out.printf("%X\n", Double.doubleToRawLongBits(n)); 
System.out.printf("%X\n", Double.doubleToLongBits(n2)); 
System.out.printf("%X\n", Double.doubleToRawLongBits(n2)); 

de salida:

7FF8000000000000 
7FF8000000000000 
7FF8000000000000 
7FF8000000000100 
+0

¡Gracias por el consejo sobre 'doubleToRawLongBits'! –

2

IEEE 754 define un NaN como un número con todos los bits de exponente que son 1 y un número distinto de cero en la mantisa.

Así que para un número de precisión simple que buscas: maneja

S  E   M 
x 11111111 xxxxxx....xxx (with M != 0) 

Java este modo:

Double n = Double.longBitsToDouble(0x7ff8000000000000L); // default NaN 
Double n2 = Double.longBitsToDouble(0x7ff8000000000100L); // also a NaN, but M != 0 

System.out.println(n.isNaN()); // true 
System.out.println(n2.isNaN()); // true 
System.out.println(n2 != Double.doubleToLongBits(Double.NaN)); // true 

En resumen, se puede utilizar cualquier NaN desea que se ajusta a la reglas antes mencionadas (todas las partes 1 en exponente y mantisa! = 0).

+0

La última declaración no tiene sentido. 'Double.doubleToLongBits (...)' es un 'long', que se convierte implícitamente en' double', autoboxed y se compara por * reference * con 'n2'. – finnw

+0

Posiblemente en la última línea debería ser 'Double.doubleToLongBits (n2)! = Double.doubleToLongBits (Double.NaN)'? –

+0

Que imprime 'falso', porque' doubleToLongBits' convierte todos 'NaN' s al mismo valor. Pero es verdad si usas 'doubleToRawLongBits'. – finnw

5

Java usa IEEE 754 para sus números de punto flotante y por lo tanto, sigue sus reglas.

De acuerdo con la Wikipedia page on NaN que se define así:

Un ejemplo bit a bit de un IEEE estándar de punto flotante de precisión simple NaN: x111 1111 1axx xxxx xxxx xxxx xxxx xxxx donde x significa no les importa.

Así que hay bastantes patrones de bits, todos los cuales son NaN valores.

+0

Gracias. ¿Está garantizado que sea portátil en todas las máquinas virtuales? –

+1

@simonn: esa pregunta me haría detenerme por un momento: ¿cómo exactamente quiere usar ese hecho? ¿Tratas de enviar información dentro de banda dentro del valor de NaN de un "doble"? –

+0

tipo de. Intento emular la semántica de un sistema en el que hay varios valores diferentes que todos actúan como NaN, pero son distinguibles. –

Cuestiones relacionadas