Tym razem co? z pozoru prostego (zreszt? jak zawsze :P)

01. public class Main {
02. public static void main(String[] args) {
03. double k = Math.sqrt(-1);
04. if (k == Double.NaN)
05. System.out.print(k);
06. System.out.print(k);
07. }
08. }


No i pytanie, jaki b?dzie efekt skompilowania i uruchomienia tego kawa?ka kodu? - tylko jedna odpowied? jest poprawna.





A. Zostanie rzucony wyj?tek ArithmeticException w linii 3
B.
Zostanie rzucony wyj?tek IllegalArgumentException w linii 3
C.
Na ekranie pojawi si? NaNNaN
D.
Na ekranie pojawi si? NaN
E. Kod si? nie skompiluje






Prawid?owa odpowied? to oczywi?cie D. Funkcja Math.sqrt dla ujemnego argumentu zwraca warto?? NaN (Not a Number). Dlaczego wi?c w linii 4 wyra?eniek k == Double.NaN ma warto?? false? Okazuje si?, ?e porównanie ze sob? 2 warto?ci NaN zwróci warto?? false. Dlatego te? warunek z linii 4 nie zostanie spe?niony i linia 5 si? nie wykona. Aby sprawdzi?, czy k ma warto?? NaN, nale?y u?y? funkcji Double.isNaN(k). Dlaczego tak jest? Otó? nie chodzi tu o specyfikacj? j?zyka Java, tylko o specyfikacj? standardu EEE 754, którego to u?ywa Java.Wi?c w C# tak?e porównanie dwóch NaN zwróci false. Zainteresowanych odsy?am do wikipedii http://en.wikipedia.org/wiki/NaN

Co ciekawe, gdyby zamieni? linie 4 powy?szego kodu na:

if (((Double)Double.NaN).equals(k))


Na ekranie wy?wietli?aby si? warto?? NaNNaN, czyli operacja equals na dwóch doublach NaN zrzutowanych na obiekty typu Double zwróci warto?? true.






More...