CodeGym /Java-Blog /Random-DE /NaN in Java
Autor
Oleksandr Miadelets
Head of Developers Team at CodeGym

NaN in Java

Veröffentlicht in der Gruppe Random-DE
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 zeroes 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. NaN in Java - 1Schauen 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 / doubleNull 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
Das Ergebnis der Division einer positiven Zahl durch 0 ist positive Unendlichkeit. Ebenso ergibt sich eine negative Unendlichkeit, wenn eine negative Zahl durch Null dividiert wird. Bitte beachten Sie, dass alle Gleitkommawerte auch für den Datentyp Double gelten. Die begrenzte Präzision von Floats ist manchmal nicht ausreichend. Wir werden jedoch in einem späteren Abschnitt sehen, wie NaN sowohl für Float als auch für Double funktioniert.

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 (==, <=, >=, <, >)
Hier ist ein funktionierendes Beispiel für euch:

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

Abschluss

Nachdem Sie sich die zahlreichen Vorgänge angesehen haben, die NaN produzieren, müssen Sie jetzt damit vertraut sein. Es mag Sie zunächst verwirren, aber es ist nicht kompliziert, damit umzugehen. Wenn Sie sich angewöhnen, bei Doppel-/Gleitkommaberechnungen zu prüfen, ob ein Wert nicht NaN ist, können Sie sich viel Ärger ersparen. Auch wenn man das zunächst vergisst, ist es völlig in Ordnung. Für kleinere Fehlerbehebungen können Sie diesen Artikel jederzeit konsultieren. Die Erstellung kompilierbaren, fehlerfreien Codes in einem Arbeitsgang ist das Ergebnis jahrelanger Erfahrung. Also lasst uns unsere Hände schmutzig machen und etwas Großartiges bauen!
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION