In Java steht „NaN“ für „Not a Number“. Es handelt sich hierbei nicht um einen Ausnahmetyp, sondern überraschenderweise ist der Datentyp von NaN auch eine Zahl. Wenn unerfahrene Programmierer es jedoch unbeabsichtigt erhalten, verwenden sie es häufig weiter in ihren Berechnungen. Daher können inkompatible Datentypen in Java bei gemeinsamer Verwendung einen auslösbaren Fehler verursachen. Es wird auch häufig angenommen, dass
java.lang.ArithmeticException: / by zero
es mit NaN identisch ist. Java behandelt beide jedoch unterschiedlich. Rätselhaft genug? Für Ihr umfassendes Verständnis analysieren wir, wie sich diese voneinander unterscheiden. Am Ende dieses Artikels erfahren Sie mehr über die möglichen Operationen, die keine Zahl (nan) erzeugen, und über einige einfache Möglichkeiten, damit umzugehen.
Was ist NaN?
Was ist NaN? „NaN“ wird, wie viele von Ihnen vermutet haben, in Java für „Keine Zahl“ verwendet. Es handelt sich um einen speziellen Gleitkommawert zur Kennzeichnung von Überläufen und Fehlern. Es wird generiert, wenn eine Gleitkommazahl durch Null geteilt wird oder wenn die Quadratwurzel einer negativen Zahl berechnet wird. Schauen Sie sich zum Beispiel den folgenden Snippet an.public class NaN
{
public static void main(String[]args)
{
System.out.println(0.0 / 0.0); //zero divided by zero
System.out.println(Math.sqrt(-1)); //take sqrt of negative number
System.out.println(10.0 % 0); //taking mod by zero
}
}
Ausgang
NaN
NaN
NaN
Im obigen Ausschnitt können Sie beobachten, dass NaN durch drei einfache Vorgänge erzeugt wird:
- Division einer
float / double
Null durch Null. - Ziehen der Wurzel einer negativen Zahl (Math.sqrt(-x)). In der Mathematik führt das Ziehen der Quadratwurzel aus einer negativen Zahl zu einer imaginären Zahl . Dieser Fall wird durch die Rückgabe von NaN in Java gelöst.
- Nimmt man eine Zahl mit Null, erhält man nach der Division eines Werts durch Null den Rest zurück. Daher wird NaN zurückgegeben.
Wie unterscheidet sich NaN von positiver und negativer Unendlichkeit?
Gemäß der IEEE 754-Spezifikation gibt es drei spezielle Gleitkomma- und Double-Werte zur Behandlung der Grenzfälle:- Positive Unendlichkeit
- Negative Unendlichkeit
- NaN
Was ist die NaN()-Methode?
isNaN()
ist eine der grundlegenden Methoden in Java, um zu überprüfen, ob es sich um einen NaN-Wert handelt oder nicht. Da wir oben drei Fälle besprochen haben, ist es an der Zeit zu testen, wie die Methode isNaN() zwischen den Werten +infinity , -infinity und NaN unterscheidet.
public class isNaN
{ public static void main(String[]args)
{
Double posInfinity = +2.0 / 0.0;
Double negInfinity = -3.5 / 0.0;
Double nanVal = 50 % 0.0;
System.out.println ("+" + posInfinity + ".IsNaN() = " + posInfinity.isNaN());
System.out.println ( negInfinity + ".IsNaN() = " + negInfinity.isNaN());
System.out.println ( nanVal + ".IsNaN() = " + nanVal.isNaN());
}
}
Ausgang
+Infinity.IsNaN() = false
-Infinity.IsNaN() = false
NaN.IsNaN() = true
Wie vergleiche ich NaN-Werte?
Jeder NaN-Wert gilt als eindeutig. Das bedeutet, dass kein einzelnes NaN einem anderen NaN gleicht. Nach diesem Prinzip ist das Ergebnis immer negativ, wenn man einen Wert mit einem anderen vergleicht. Da NaN ungeordnet ist, liefert ein numerischer Vergleich, der auch nur ein einzelnes NaN umfasst, den Wert „Falsch“. Java stellt Float.NaN und Double.NaN für konstante Felder in beiden Klassen bereit, um Vergleiche durchzuführen. Wir können diese in zwei separate Szenarien unterscheiden:- Richtig: Nur bei Ungleichheit (!=)
- Falsch: Für alle Vergleichsoperanden (==, <=, >=, <, >)
public class ComparingNaN
{ public static void main(String[] args)
{
// Comparing NaN values for Float constants
System.out.println (Float.NaN != Float.NaN); // true
System.out.println (Float.NaN == Float.NaN); // false
System.out.println (Float.NaN < Float.NaN); // false
System.out.println (Float.NaN > Float.NaN); // false
System.out.println (Float.NaN <= Float.NaN); // false
System.out.println (Float.NaN >= Float.NaN); // false
// Comparing NaN values for Float constants
System.out.println (Double.NaN != Double.NaN); // true
System.out.println (Double.NaN == Double.NaN); // false
System.out.println (Double.NaN < Double.NaN); // false
System.out.println (Double.NaN > Double.NaN); // false
System.out.println (Double.NaN <= Double.NaN); // false
System.out.println (Double.NaN >= Double.NaN); // false
}
}
Wie generiert man NaN-Werte?
Bevor wir zum Schluss kommen, schauen wir uns einige gängige Beispiele für den Erhalt einer Not a Number (nan) an.public class GenerateNaNValues {
static final float ZERO = 0;
public static void main (String[]args)
{
System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
System.out.println("+INFINITY - INFINITY = " +
(Float.POSITIVE_INFINITY + Float.NEGATIVE_INFINITY));
System.out.println("-INFINITY * ZERO = " + (Float.NEGATIVE_INFINITY * ZERO));
System.out.println("+INFINITY * ZERO = " + (Float.POSITIVE_INFINITY * ZERO));
System.out.println("log10(-10) = " + Math.log(-10));
System.out.println("√-10 = " + Math.sqrt(-10));
System.out.println("NaN + 10 = " + (Float.NaN + 10));
System.out.println("NaN - 10 = " + (Float.NaN - 10));
System.out.println("NaN * 10 = " + (Float.NaN * 10));
System.out.println("NaN / 10 = " + (Float.NaN / 10));
System.out.println("NaN + NaN = " + (Float.NaN + Float.NaN));
System.out.println("NaN - NaN = " + (Float.NaN - Float.NaN));
System.out.println("NaN * NaN = " + (Float.NaN * Float.NaN));
System.out.println("NaN / NaN = " + (Float.NaN / Float.NaN));
}
}
Ausgang:
ZERO / ZERO = NaN
+INFINITY - INFINITY = NaN
-INFINITY * ZERO = NaN
+INFINITY * ZERO = NaN
log10(-10) = NaN
√-10 = NaN
NaN + 10 = NaN
NaN - 10 = NaN
NaN * 10 = NaN
NaN / 10 = NaN
NaN + NaN = NaN
NaN - NaN = NaN
NaN * NaN = NaN
NaN / NaN = NaN