NaN in Java

1. Übersicht

Einfach ausgedrückt ist NaN ein numerischer Datentypwert, der für „keine Zahl“ steht.

In diesem kurzen Tutorial erklären wir den NaN- Wert in Java und die verschiedenen Operationen, die diesen Wert erzeugen oder einbeziehen können.

2. Was ist NaN ?

NaN zeigt normalerweise das Ergebnis ungültiger Operationen an. Der Versuch, Null durch Null zu teilen, ist beispielsweise eine solche Operation.

Wir verwenden NaN auch für nicht darstellbare Werte. Die Quadratwurzel von -1 ist ein solcher Fall, da wir den Wert ( i ) nur in komplexen Zahlen beschreiben können.

Der IEEE-Standard für Gleitkomma-Arithmetik (IEEE 754) definiert den NaN- Wert. In Java setzen die Gleitkommatypen float und double diesen Standard um.

Java definiert NaN- Konstanten vom Typ float und double als Float .NaN und Double.NaN :

Eine Konstante, die einen NaN-Wert (Not-a-Number) vom Typ double enthält. Dies entspricht dem von Double.longBitsToDouble (0x7ff8000000000000L) zurückgegebenen Wert. “

und:

„Eine Konstante, die einen NaN-Wert (Not-a-Number) vom Typ float enthält. Dies entspricht dem von Float.intBitsToFloat (0x7fc00000) zurückgegebenen Wert. “

Wir haben diese Art von Konstanten für andere numerische Datentypen in Java nicht.

3. Vergleiche mit NaN

Beim Schreiben von Methoden in Java sollten wir überprüfen, ob die Eingabe gültig ist und innerhalb des erwarteten Bereichs liegt. Der NaN- Wert ist in den meisten Fällen keine gültige Eingabe. Daher sollten wir überprüfen, ob der Eingabewert kein NaN- Wert ist, und diese Eingabewerte entsprechend behandeln.

NaN kann nicht mit einem schwebenden Wert verglichen werden. Dies bedeutet, dass wir für alle Vergleichsoperationen mit NaN falsch werden (außer "! =", Für die wir wahr werden ).

Wir bekommen wahr für „ x = x“ , wenn und nur wenn x ist NaN:

System.out.println("NaN == 1 = " + (NAN == 1)); System.out.println("NaN > 1 = " + (NAN > 1)); System.out.println("NaN < 1 = " + (NAN  NaN = " + (NAN > NAN)); System.out.println("NaN < NaN = " + (NAN < NAN)); System.out.println("NaN != NaN = " + (NAN != NAN)); 

Schauen wir uns das Ergebnis der Ausführung des obigen Codes an:

NaN == 1 = false NaN > 1 = false NaN  NaN = false NaN < NaN = false NaN != NaN = true 

Daher können wir nicht nach NaN suchen, indem wir mit „==“ oder „! =“ Mit NaN vergleichen . Tatsächlich sollten wir selten Operatoren "==" oder "! =" Mit Float- oder Double- Typen verwenden.

Stattdessen können wir den Ausdruck „ x! = x ” . Dieser Ausdruck gibt nur für NAN true zurück .

Wir können auch die Methoden Float.isNaN und Double.isNaN verwenden , um nach diesen Werten zu suchen . Dies ist der bevorzugte Ansatz, da er besser lesbar und verständlicher ist:

double x = 1; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x))); x = Double.NaN; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x))); 

Wenn Sie diesen Code ausführen, erhalten Sie das folgende Ergebnis:

1.0 is NaN = false 1.0 is NaN = false NaN is NaN = true NaN is NaN = true

4. Operationen, die NaN produzieren

Bei Operationen mit Float- und Double- Typen müssen wir die NaN- Werte kennen.

Einige Gleitkomma-Methoden und -Operationen erzeugen NaN- Werte, anstatt eine Ausnahme auszulösen. Möglicherweise müssen wir solche Ergebnisse explizit behandeln.

Ein häufiger Fall, der zu Nicht-Zahlen-Werten führt, sind mathematisch undefinierte numerische Operationen :

double ZERO = 0; System.out.println("ZERO / ZERO = " + (ZERO / ZERO)); System.out.println("INFINITY - INFINITY = " + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY)); System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO)); 

Diese Beispiele führen zu folgender Ausgabe:

ZERO / ZERO = NaN INFINITY - INFINITY = NaN INFINITY * ZERO = NaN 

Numerische Operationen, die nicht zu reellen Zahlen führen, erzeugen ebenfalls NaN:

System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1)); System.out.println("LOG OF -1 = " + Math.log(-1)); 

Diese Aussagen führen zu:

SQUARE ROOT OF -1 = NaN LOG OF -1 = NaN 

Alle numerischen Operationen mit NaN als Operanden erzeugen NaN als Ergebnis:

System.out.println("2 + NaN = " + (2 + Double.NaN)); System.out.println("2 - NaN = " + (2 - Double.NaN)); System.out.println("2 * NaN = " + (2 * Double.NaN)); System.out.println("2 / NaN = " + (2 / Double.NaN)); 

Und das Ergebnis des oben genannten ist:

2 + NaN = NaN 2 - NaN = NaN 2 * NaN = NaN 2 / NaN = NaN 

Schließlich können wir nicht assign null auf doppelte oder float Typ Variablen. Stattdessen können wir solchen Variablen explizit NaN zuweisen , um fehlende oder unbekannte Werte anzuzeigen:

double maxValue = Double.NaN;

5. Schlussfolgerung

In diesem Artikel haben wir NaN und die verschiedenen damit verbundenen Operationen besprochen . Wir haben auch die Notwendigkeit diskutiert, NaN zu behandeln, während Gleitkommaberechnungen in Java explizit durchgeführt werden.

Den vollständigen Quellcode finden Sie auf GitHub.