Questo esempio può aiutarti a capire:
codice:
public class GetNan {
public static void main(String[] args) {
float f1 = 0.0f / 0.0f;
float f2 = (float) Math.sqrt( -16.0d );
System.out.println("Verifichiamo che i due valori siano NaN:");
System.out.println("f1: " + f1);
System.out.println("f2: " + f2);
System.out.println();
System.out.println("Vediamo le rappresentazioni intere dei due NaN:");
System.out.println("f1: " + Integer.toHexString(Float.floatToIntBits(f1)));
System.out.println("f1 (row): " + Integer.toHexString(Float.floatToRawIntBits(f1)));
System.out.println("f2: " + Integer.toHexString(Float.floatToIntBits(f2)));
System.out.println("f2 (row): " + Integer.toHexString(Float.floatToRawIntBits(f2)));
}
}
L'output è il seguente:
codice:
Verifichiamo che i due valori siano NaN:
f1: NaN
f2: NaN
Vediamo le rappresentazioni intere dei due NaN:
f1: 7fc00000
f1 (row): 7fc00000
f2: 7fc00000
f2 (row): ffc00000
All'inizio vengono calcolati due valori NaN: il risultato della divisione 0/0 ed il calcolo della radice quadrata di un numero negativo.
Il programma verifica che i due valori siano effettivamente NaN, stampandoli a video.
Poi stampa le rappresentazioni intere dei due float.
Nel primo caso, floatToIntBits e floatToRowIntBits producolo lo stesso identico risultato; ciò significa che il risultato della divisione per 0 viene rappresentato (ed è piuttosto ovvio) tramite una sequenza di bit che è la stessa usata per la rappresentazione canonica di NaN.
Nel secondo caso, invece, floatToIntBits ritorna la rappresentazione canonica di NaN (come ci si aspetta), mentre floatToRowIntBits ritorna l'effettiva rappresentazione in memoria di quel float (che è sempre un NaN).
Questo ci dimostra che NaN non è un valore particolare, ma è NaN qualunque sequenza di bit che non rappresenta un float secondo lo standard IEEE 754 (e ce ne sono molte di sequenze di bit che non rappresentano un float... ne è un esempio la sequenza di bit "ffc00000").
Ciao.