2010-01-28 16 views
8

documentation for java.lang.Double.NaN mówi, że jestJakie są inne wartości NaN?

Stała trzyma Not-a-Number (NaN) wartość typu double. Jest to odpowiednik wartości zwróconej przez Double.longBitsToDouble(0x7ff8000000000000L).

Wydaje się to sugerować, że są inne. Jeśli tak, jak mogę je zdobyć i czy można to zrobić przenośnie?

Żeby było jasne, chciałbym znaleźć wartości doublex takie, że

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

i

Double.isNaN(x) 

są zarówno prawdziwe.

+0

Czy to znaczy istnieją inne 'java.lang * NaN'..? –

+0

@Dominic: Nie - dodałem to, co według mnie jest wyjaśnieniem tego pytania. –

Odpowiedz

8

Potrzebujesz doubleToRawLongBits zamiast doubleToLongBits.

doubleToRawLongBits wyodrębnia rzeczywistą reprezentację binarną. doubleToLongBits nie, najpierw konwertuje wszystkie NaN s na domyślne NaN s.

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)); 

wyjściowa:

7FF8000000000000 
7FF8000000000000 
7FF8000000000000 
7FF8000000000100 
+0

Dzięki za podpowiedź o "doubleToRawLongBits"! –

2

IEEE 754 definiuje NaN jako liczbę ze wszystkimi bitami potęgowymi, które są 1 i liczbą niezerową w mantysie.

więc dla pewnej liczby pojedynczej precyzji szukasz: uchwyty

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

Java to tak:

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 

Podsumowując, można użyć dowolnego NaN chcesz, który odpowiada zasady wyżej wymienione (wszystkie bity 1 w wykładniku i mantysa! = 0).

+0

Ostatnie stwierdzenie nie ma sensu. 'Double.doubleToLongBits (...)' to 'long', który jest niejawnie konwertowany na' double', autoboxed i porównywany przez * reference * do 'n2'. – finnw

+0

Prawdopodobnie w ostatnim wierszu powinno być 'Double.doubleToLongBits (n2)! = Double.doubleToLongBits (Double.NaN)'? –

+0

To wypisze 'false', ponieważ' doubleToLongBits' zamienia wszystkie 'NaN's na tę samą wartość. Ale to prawda, jeśli używasz 'doubleToRawLongBits'. – finnw

5

Java używa IEEE 754 dla swoich liczb zmiennoprzecinkowych i dlatego przestrzega ich zasad.

Według Wikipedia page on NaN jest zdefiniowany następująco:

przykładem bitową z IEEE zmiennoprzecinkowych pojedynczej precyzji standardowej NaN: x111 1111 1axx xxxx xxxx xxxx xxxx xxxx gdzie x oznacza nie obchodzi.

Tak więc istnieje wiele wzorców bitowych, z których wszystkie są wartościami NaN.

+0

Dzięki. Czy to gwarantuje przenośność w maszynach wirtualnych? –

+1

@simonn: to pytanie spowodowałoby, żebym zatrzymał się na chwilę: Jak dokładnie chcesz skorzystać z tego faktu? Czy próbujesz przesłać informacje wewnątrz zespołu w wartości NaN "podwójnego"? –

+0

Sortuj. Próbuję naśladować semantykę systemu, w którym istnieje kilka różnych wartości, które działają jak NaN, ale są one możliwe do odróżnienia. –

Powiązane problemy