John Squirrels
Nivå
San Francisco

NaN i Java

Publisert i gruppen
I Java står "NaN" for "Not a Number". Det er ikke en type unntak, ganske overraskende er datatypen til NaN også et tall. Men ofte når nybegynnere programmerere får det utilsiktet, bruker de det videre i sine beregninger. Derfor kan inkompatible datatyper i Java når de brukes sammen forårsake en kastbar feil. Det er også ofte sett som java.lang.ArithmeticException: / by zeroregnes som det samme som NaN. Java behandler dem begge forskjellig. Forvirrende nok? For din omfattende forståelse vil vi dissekere hvordan disse er forskjellige fra hverandre. Mot slutten av denne artikkelen vil du lære om mulige operasjoner som ikke produserer et tall (nan), og noen enkle måter å håndtere det på.

Hva er NaN?

Så, hva er NaN? "NaN" som mange av dere har gjettet, brukes til å representere "Not a Number" i Java. Det er en spesiell flyttallsverdi for å betegne overløp og feil. Det genereres når et flyttall er delt på null eller hvis kvadratroten av et negativt tall beregnes. NaN i Java - 1Ta for eksempel en titt på følgende utdrag.

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

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
I utdraget ovenfor kan du observere at NaN produseres som et resultat av 3 enkle operasjoner:
  • Å dele en float / doublenull med null.
  • Ta under roten av et negativt tall (Math.sqrt(-x)). I matematikk resulterer det å ta kvadratroten av et negativt tall i et tenkt tall . Denne saken behandles ved å returnere NaN i Java.
  • Å ta mod av et tall med null, vil returnere resten etter å ha delt en verdi med null. Derfor returneres NaN.

Hvordan er NaN forskjellig fra positiv og negativ uendelighet?

I henhold til IEEE 754-spesifikasjonen er det tre spesielle flyttall- og doble verdier for å håndtere grensetilfellene:
  • Positiv uendelighet
  • Negativ uendelighet
  • NaN
Resultatet av å dele et positivt tall med 0 er positiv uendelig. På samme måte gir negativ uendelighet som et resultat av å dele et negativt tall med null. Vær oppmerksom på at alle flyttallverdier også gjelder for datatypen dobbel. Den begrensede presisjonen til flottører er til tider ikke tilstrekkelig. Vi vil imidlertid se hvordan NaN fungerer for både float og double i et senere avsnitt.

Hva er NaN()-metoden?

isNaN()er en av de grunnleggende metodene i Java for å sjekke om det er en NaN-verdi eller ikke. Som vi diskuterte tre tilfeller ovenfor, er det på tide å teste hvordan isNaN()-metoden skiller mellom +infinity , -infinity og NaN-verdier.

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

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

Hvordan sammenligne NaN-verdier?

Hver NaN-verdi regnes som distinkt. Dette betyr at ikke en eneste NaN er lik noen annen NaN. Etter dette prinsippet, hvis du sammenligner en verdi med en annen, er resultatet alltid negativt. Siden NaN er uordnet, så en numerisk sammenligning som involverer til og med en enkelt NaN returnerer falsk. Java gir Float.NaN og Double.NaN for konstante felt i begge klassene for å utføre sammenligninger. Vi kan skille disse i to separate scenarier:
  • Sant: Bare i tilfelle ulikhet (!=)
  • False: For alle sammenligningsoperander (==, <=, >=, <, >)
Her er et fungerende eksempel for dere:

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

Hvordan generere NaN-verdier?

Før vi avslutter, la oss se på noen vanlige eksempler på å få et 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));
  }
}
Produksjon:

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

Konklusjon

Etter å ha sett på de mange operasjonene som produserer NaN, må du være kjent med det nå. Det kan forvirre deg i begynnelsen, men det er ikke noe komplisert å håndtere dette. Ved å utvikle en liten vane med å sjekke om en verdi ikke er NaN i dobbel/flytpoengberegninger kan du spare deg for mye bryderi. Selv om du glemmer dette først, er det helt greit. Du kan alltid konsultere denne artikkelen for mindre feilsøking. Å lage kompilerbar, feilfri kode på én gang kommer etter mange års erfaring. Så la oss skitne i koden og bygge noe flott!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION