CodeGym /Java Blog /Random-IT /NaN in Java
John Squirrels
Livello 41
San Francisco

NaN in Java

Pubblicato nel gruppo Random-IT
In Java, "NaN" sta per "Not a Number". Non è un tipo di eccezione, piuttosto sorprendentemente, anche il tipo di dati di NaN è un numero. Ma spesso quando i programmatori alle prime armi lo ottengono involontariamente, lo usano ulteriormente nei loro calcoli. Pertanto, i tipi di dati incompatibili in Java se usati insieme possono causare un errore generabile. È anche comunemente visto che java.lang.ArithmeticException: / by zeroè considerato lo stesso di NaN. Tuttavia, Java li tratta entrambi in modo diverso. Abbastanza sconcertante? Per la tua comprensione completa, analizzeremo come questi sono diversi l'uno dall'altro. Alla fine di questo articolo imparerai le possibili operazioni che producono non un numero (nan) e alcuni semplici modi per gestirlo.

Cos'è NaN?

Allora, cos'è il NaN? "NaN", come molti di voi hanno intuito, è usato per rappresentare "Not a Number" in Java. È un valore a virgola mobile speciale per indicare overflow ed errori. Viene generato quando un numero in virgola mobile viene diviso per zero o se viene calcolata la radice quadrata di un numero negativo. NaN in Java - 1Ad esempio, dai un'occhiata al seguente frammento.

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

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
Nello snippet sopra, puoi osservare che NaN viene prodotto come risultato di 3 semplici operazioni:
  • Dividere uno float / doublezero con zero.
  • Prendendo sottoradice di un numero negativo (Math.sqrt(-x)). In matematica, estraendo la radice quadrata di un numero negativo si ottiene un numero immaginario . Questo caso viene risolto restituendo NaN in Java.
  • Prendendo mod di un numero con zero, restituirà il resto dopo aver diviso un valore per zero. Quindi, viene restituito NaN.

In che modo NaN è diverso dall'infinito positivo e negativo?

Secondo le specifiche IEEE 754, ci sono tre speciali valori a virgola mobile e doppi per gestire i casi limite:
  • Infinito positivo
  • Infinito negativo
  • NaN
Il risultato della divisione di un numero positivo per 0 è infinito positivo. Allo stesso modo, l'infinito negativo produce come risultato della divisione di un numero negativo per zero. Si noti che tutti i valori in virgola mobile sono applicabili anche al tipo di dati double. La limitata precisione dei float a volte non è sufficiente. Tuttavia, vedremo come funziona NaN sia per float che per double in una sezione successiva.

Cos'è il metodo NaN()?

isNaN()è uno dei metodi di base in Java per verificare se si tratta di un valore NaN o meno. Come abbiamo discusso tre casi sopra, è il momento di testare come il metodo isNaN() distingue tra i valori +infinity , -infinity e 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());
  }
}
Produzione

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

Come confrontare i valori NaN?

Ogni valore NaN è considerato distinto. Ciò significa che nessun NaN è uguale a nessun altro NaN. In base a questo principio, se confronti un valore con un altro il risultato è sempre negativo. Poiché NaN non è ordinato, un confronto numerico che coinvolge anche un solo NaN restituisce false. Java fornisce Float.NaN e Double.NaN per campi costanti in entrambe le classi per eseguire confronti. Possiamo differenziarli in due scenari separati:
  • Vero: solo in caso di disuguaglianza (!=)
  • Falso: per tutti gli operandi di confronto (==, <=, >=, <, >)
Ecco un esempio funzionante per voi ragazzi:

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

Come generare valori NaN?

Prima di concludere, diamo un'occhiata ad alcuni esempi comuni di come ottenere un 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));
  }
}
Produzione:

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

Conclusione

Dopo aver esaminato le numerose operazioni che producono NaN, ora devi conoscerlo. Inizialmente potrebbe lasciarti perplesso, ma non c'è nulla di complicato nell'affrontarlo. Sviluppando una piccola abitudine di verificare se un valore non è NaN nei calcoli in virgola mobile/doppio può salvarti da un sacco di seccature. Anche se lo dimentichi inizialmente, va benissimo. Puoi sempre consultare questo articolo per la risoluzione di problemi minori. La creazione di codice compilabile e privo di errori in una volta sola arriva dopo anni di esperienza. Quindi sporchiamoci le mani nel codice e costruiamo qualcosa di eccezionale!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION