NaN in Java

NaN in Java

1. Überblick

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

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

2. Was istNaN?

NaN usually indicates the result of invalid operations. Der Versuch, Null durch Null zu teilen, ist beispielsweise eine solche Operation.

We also use NaN for unrepresentable values. Die Quadratwurzel von -1 ist ein solcher Fall, da wir den Wert (i) nur in komplexen Zahlen beschreiben können.

DasIEEE Standard for Floating-Point Arithmetic (IEEE 754) definiert denNaN-Wert. In Java, the floating-point types float and double implement this standard.

Java definiertNaN Konstanten der Typenfloat unddouble alsFloat.NaN undDouble.NaN:

A constant holding a Not-a-Number (NaN) value of type double. It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L).”

and:

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

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

3. Vergleiche mitNaN

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

NaN kann nicht mit einem schwebenden Wert verglichen werden. Dies bedeutet, dass wirfalse für alle Vergleichsoperationen erhalten, an denenNaN beteiligt sind (außer "! =", Für die wirtrue erhalten).

Wir erhaltentrue für „x != x” genau dann, wennxNaN: ist

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

Werfen wir einen Blick auf das Ergebnis der obigen Code-Ausführung:

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

Daherwe cannot check for NaN by comparing with NaN using “==” or “!= “. Tatsächlich sollten wir selten Operatoren "==" oder "! =" Mit den Typenfloat oderdouble verwenden.

Stattdessen können wir den Ausdruck "x ! = x". verwenden. Dieser Ausdruck gibt nur fürNAN. true zurück

Wir können auch die MethodenFloat.isNaN undDouble.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)));

Bei der Ausführung dieses Codes erhalten wir das folgende Ergebnis:

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

4. Operationen, dieNaN produzieren

Bei Operationen mit den Typenfloat unddouble müssen die Werte vonNaN berücksichtigt werden.

Some floating-point methods and operations produce NaN values instead of throwing an Exception. Möglicherweise müssen wir solche Ergebnisse explizit behandeln.

Ein häufiger Fall, der zu Werten führt, die keine Zahl sind, sindmathematically undefined numerical operations:

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 keine reellen Zahlen ergeben, erzeugen ebenfallsNaN:

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 mitNaN als Operanden erzeugenNaN 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 wirdouble oderfloat Variablen vom Typnull nicht zuweisen. Stattdessen können wir solchen Variablen explizitNaN zuweisen, um fehlende oder unbekannte Werte anzuzeigen:

double maxValue = Double.NaN;

5. Fazit

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

Der vollständige Quellcode istover on GitHub.