NaN in Java

1. Overzicht

Simpel gezegd, NaN is een numerieke waarde van het gegevenstype die staat voor "geen getal".

In deze korte tutorial leggen we de NaN waarde in Java en de verschillende bewerkingen die deze waarde kunnen produceren of betrekken.

2. Wat is NaN?

NaN geeft meestal het resultaat van ongeldige bewerkingen aan. Een poging om nul door nul te delen, is bijvoorbeeld zo'n bewerking.

We gebruiken ook NaN voor onvoorstelbare waarden. De vierkantswortel van -1 is zo'n geval, omdat we de waarde (ik) alleen in complexe getallen.

De IEEE Standard for Floating-Point Arithmetic (IEEE 754) definieert de NaN waarde. In Java zijn de typen met drijvende komma vlotter en dubbele implementeer deze norm.

Java definieert NaN constanten van beide vlotter en dubbele typen als Vlotter.NaN en Double.NaN:

Een constante met een Not-a-Number (NaN) -waarde van het type double. Het is gelijk aan de waarde die wordt geretourneerd door Double.longBitsToDouble (0x7ff8000000000000L). "

en:

“Een constante met een Not-a-Number (NaN) -waarde van het type float. Het is gelijk aan de waarde die wordt geretourneerd door Float.intBitsToFloat (0x7fc00000). "

We hebben dit type constanten niet voor andere numerieke gegevenstypen in Java.

3. Vergelijkingen met NaN

Tijdens het schrijven van methoden in Java, moeten we controleren of de invoer geldig is en binnen het verwachte bereik. NaN waarde is in de meeste gevallen geen geldige invoer. Daarom moeten we controleren of de invoerwaarde geen NaN waarde en behandel deze invoerwaarden op de juiste manier.

NaN kan niet worden vergeleken met een waarde van het zwevende type. Dit betekent dat we zullen krijgen false voor alle vergelijkingsoperaties waarbij NaN (behalve "! =" waarvoor we krijgen waar).

We krijgen waar voor "x! = x " als en alleen als X is NaN:

System.out.println ("NaN == 1 =" + (NAN == 1)); System.out.println ("NaN> 1 =" + (NAN> 1)); System.out.println ("NaN <1 =" + (NAN NaN = "+ (NAN> NAN)); System.out.println (" NaN <NaN = "+ (NAN <NAN)); System.out. println ("NaN! = NaN =" + (NAN! = NAN)); 

Laten we eens kijken naar het resultaat van het uitvoeren van de bovenstaande code:

NaN == 1 = niet waar NaN> 1 = niet waar NaN NaN = niet waar NaN <NaN = niet waar NaN! = NaN = waar 

Vandaar, we kunnen niet controleren NaN door te vergelijken met NaN met "==" of "! =". In feite zouden we zelden de operatoren "==" of "! =" Moeten gebruiken met vlotter of dubbele types.

In plaats daarvan kunnen we de uitdrukking 'x!= x ”. Deze expressie retourneert alleen true voor NAN.

We kunnen ook de methoden gebruiken Float.isNaN en Double.isNaN om deze waarden te controleren. Dit heeft de voorkeur, aangezien deze beter leesbaar en begrijpelijker is:

dubbele x = 1; System.out.println (x + "is NaN =" + (x! = X)); System.out.println (x + "is NaN =" + (Double.isNaN (x))); x = Double.NaN; System.out.println (x + "is NaN =" + (x! = X)); System.out.println (x + "is NaN =" + (Double.isNaN (x))); 

We krijgen het volgende resultaat wanneer we deze code uitvoeren:

1,0 is NaN = onwaar 1,0 is NaN = onwaar NaN is NaN = waar NaN is NaN = waar

4. Operaties produceren NaN

Tijdens het uitvoeren van bewerkingen waarbij vlotter en dubbele typen, moeten we ons bewust zijn van de NaN waarden.

Sommige drijvende-kommamethoden en -bewerkingen produceren NaN waarden in plaats van een Uitzondering. Het is mogelijk dat we dergelijke resultaten expliciet moeten behandelen.

Een veelvoorkomend geval dat resulteert in not-a-number-waarden zijn wiskundig ongedefinieerde numerieke bewerkingen:

dubbele NUL = 0; System.out.println ("ZERO / ZERO =" + (ZERO / ZERO)); System.out.println ("INFINITY - INFINITY =" + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY)); System.out.println ("INFINITY * ZERO =" + (Double.POSITIVE_INFINITY * ZERO)); 

Deze voorbeelden resulteren in de volgende uitvoer:

NUL / NUL = NaN INFINITY - INFINITY = NaN INFINITY * NUL = NaN 

Numerieke bewerkingen die geen resultaten in reële getallen opleveren, leveren ook op NaN:

System.out.println ("VIERKANTE WORTEL VAN -1 =" + Math.sqrt (-1)); System.out.println ("LOG OF -1 =" + Math.log (-1)); 

Deze uitspraken zullen resulteren in:

VIERKANTE WORTEL VAN -1 = NaN LOG VAN -1 = NaN 

Alle numerieke bewerkingen met NaN als een operand produceren NaN als resultaat:

System.out.println ("2 + NaN =" + (2 + Double.NaN)); System.out.println ("2 - NaN =" + (2 - Double.NaN)); System.out.println ("2 * NaN =" + (2 * Double.NaN)); System.out.println ("2 / NaN =" + (2 / Double.NaN)); 

En het resultaat van het bovenstaande is:

2 + NaN = NaN 2 - NaN = NaN 2 * NaN = NaN 2 / NaN = NaN 

Ten slotte kunnen we niet toewijzen nul naar dubbele of vlotter type variabelen. In plaats daarvan kunnen we expliciet toewijzen NaN op dergelijke variabelen om ontbrekende of onbekende waarden aan te geven:

double maxValue = Double.NaN;

5. Conclusie

In dit artikel hebben we besproken NaN en de verschillende operaties die ermee gepaard gaan. We bespraken ook de noodzaak om aan te pakken NaN tijdens het expliciet uitvoeren van drijvende-kommaberekeningen in Java.

De volledige broncode is te vinden op GitHub.