CodeGym /Java Blog /Willekeurig /NaN op Java
John Squirrels
Niveau 41
San Francisco

NaN op Java

Gepubliceerd in de groep Willekeurig
In Java staat "NaN" voor "Not a Number". Het is geen soort uitzondering, nogal verrassend, het datatype van NaN is ook een nummer. Maar vaak, wanneer beginnende programmeurs het onbedoeld krijgen, gebruiken ze het verder in hun berekeningen. Daarom kunnen incompatibele gegevenstypen in Java, wanneer ze samen worden gebruikt, een fout veroorzaken. Het wordt ook vaak gezien als java.lang.ArithmeticException: / by zerohetzelfde als NaN. Java behandelt ze echter allebei anders. Puzzelen genoeg? Voor uw uitgebreide begrip zullen we ontleden hoe deze van elkaar verschillen. Aan het einde van dit artikel leer je over de mogelijke bewerkingen die geen getal produceren (nan), en enkele eenvoudige manieren om ermee om te gaan.

Wat is NaN?

Dus, wat is NaN? "NaN", zoals velen van jullie al geraden hebben, wordt gebruikt om "Geen nummer" in Java weer te geven. Het is een speciale drijvende-kommawaarde om overflows en fouten aan te duiden. Het wordt gegenereerd wanneer een getal met drijvende komma wordt gedeeld door nul of als de vierkantswortel van een negatief getal wordt berekend. NaN in Java - 1Kijk bijvoorbeeld eens naar het volgende fragment.

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	
    }
}
Uitgang

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
In het bovenstaande fragment kunt u zien dat NaN wordt geproduceerd als resultaat van 3 eenvoudige bewerkingen:
  • Een nul delen float / doubledoor nul.
  • Onderwortel nemen van een negatief getal (Math.sqrt(-x)). In de wiskunde resulteert het nemen van de vierkantswortel van een negatief getal in een imaginair getal . Deze zaak wordt afgehandeld door NaN terug te sturen in Java.
  • Door mod te nemen van een getal met nul, wordt de rest geretourneerd na het delen van een waarde door nul. Daarom wordt NaN geretourneerd.

Hoe verschilt NaN van positieve en negatieve oneindigheid?

Volgens de IEEE 754-specificatie zijn er drie speciale drijvende-komma- en dubbele waarden om de grensgevallen af ​​te handelen:
  • Positieve oneindigheid
  • Negatieve oneindigheid
  • NaN
Het resultaat van het delen van een positief getal door 0 is positief oneindig. Evenzo levert negatieve oneindigheid op als resultaat van het delen van een negatief getal door nul. Houd er rekening mee dat alle drijvende-kommawaarden ook van toepassing zijn op het gegevenstype double. De beperkte precisie van drijvers is soms niet voldoende. We zullen in een later gedeelte echter zien hoe NaN werkt voor zowel float als double.

Wat is de NaN()-methode?

isNaN()is een van de basismethoden in Java om te controleren of het een NaN-waarde is of niet. Zoals we hierboven drie gevallen hebben besproken, is het tijd om te testen hoe de methode isNaN() onderscheid maakt tussen de waarden +infinity , -infinity en NaN.

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());
  }
}
Uitgang

+Infinity.IsNaN() = false                                                                                                                       
-Infinity.IsNaN() = false                                                                                                                       
NaN.IsNaN() = true

Hoe NaN-waarden vergelijken?

Elke NaN-waarde wordt als verschillend beschouwd. Dit betekent dat geen enkele NaN gelijk is aan een andere NaN. Volgens dit principe is het resultaat altijd negatief als u de ene waarde met de andere vergelijkt. Omdat NaN ongeordend is, retourneert een numerieke vergelijking waarbij zelfs maar één NaN betrokken is onwaar. Java biedt Float.NaN en Double.NaN voor constante velden in beide klassen om vergelijkingen uit te voeren. We kunnen deze onderscheiden in twee afzonderlijke scenario's:
  • Waar: alleen in geval van ongelijkheid (!=)
  • False: voor alle vergelijkingsoperanden (==, <=, >=, <, >)
Hier is een werkend voorbeeld voor jullie:

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
  }
}

Hoe NaN-waarden genereren?

Laten we, voordat we afronden, eens kijken naar enkele veelvoorkomende voorbeelden van het krijgen van een Not a Number (nan).

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));
  }
}
Uitgang:

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

Conclusie

Na het bekijken van de vele bewerkingen die NaN produceren, moet u er nu bekend mee zijn. Het kan je in eerste instantie verwarren, maar er is niets ingewikkelds aan om hiermee om te gaan. Door een kleine gewoonte te ontwikkelen om te controleren of een waarde niet NaN is in berekeningen met dubbele/zwevende komma, kunt u een hoop gedoe besparen. Zelfs als je dit in eerste instantie vergeet, is het helemaal goed. U kunt dit artikel altijd raadplegen voor kleine probleemoplossing. Het in één keer compileren van foutloze code is het resultaat van jarenlange ervaring. Dus laten we onze handen vuil maken in code en iets geweldigs bouwen!
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION