NaN i Java

1. Oversikt

For å si det enkelt, NaN er en numerisk datatypeverdi som står for “ikke et tall”.

I denne raske opplæringen forklarer vi NaN verdi i Java og de forskjellige operasjonene som kan produsere eller involvere denne verdien.

2. Hva er? NaN?

NaN indikerer vanligvis resultatet av ugyldige operasjoner. For eksempel å prøve å dele null med null er en slik operasjon.

Vi bruker også NaN for urepresenterbare verdier. Kvadratroten til -1 er et slikt tilfelle, ettersom vi kan beskrive verdien (Jeg) bare i komplekse tall.

IEEE Standard for Floating-Point Arithmetic (IEEE 754) definerer NaN verdi. I Java, typene flytende punkt flyte og dobbelt implementere denne standarden.

Java definerer NaN konstanter av begge deler flyte og dobbelt typer som Flyte.NaN og Dobbelt.NaN:

En konstant som holder en Not-a-Number (NaN) verdi av typen dobbelt. Det tilsvarer verdien som returneres av Double.longBitsToDouble (0x7ff8000000000000L). ”

og:

“En konstant holder en Not-a-Number (NaN) verdi av typen float. Det tilsvarer verdien som returneres av Float.intBitsToFloat (0x7fc00000). ”

Vi har ikke denne typen konstanter for andre numeriske datatyper i Java.

3. Sammenligninger med NaN

Mens du skriver metoder i Java, bør vi sjekke at inngangen er gyldig og innenfor forventet område. NaN verdi er i de fleste tilfeller ikke gyldig. Derfor bør vi verifisere at inngangsverdien ikke er a NaN verdi og håndter disse inngangsverdiene riktig.

NaN kan ikke sammenlignes med noen flytende typeverdi. Dette betyr at vi får falsk for alle sammenligningsoperasjoner som involverer NaN (unntatt “! =” som vi får ekte).

Vi får ekte for “x! = x ” hvis og bare hvis x er 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)); 

La oss ta en titt på resultatet av å kjøre koden ovenfor:

NaN == 1 = falsk NaN> 1 = falsk NaN NaN = falsk NaN <NaN = falsk NaN! = NaN = sann 

Derfor, vi kan ikke se etter NaN ved å sammenligne med NaN ved hjelp av “==” eller “! =“. Vi bør faktisk sjelden bruke "==" eller "! =" Operatører med flyte eller dobbelt typer.

I stedet kan vi bruke uttrykket “x!= x ”. Dette uttrykket blir sant bare for NAN.

Vi kan også bruke metodene Float.isNaN og Double.isNaN for å se etter disse verdiene. Dette er den foretrukne tilnærmingen siden den er mer lesbar og forståelig:

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

Vi får følgende resultat når du kjører denne koden:

1.0 er NaN = falsk 1.0 er NaN = falsk NaN er NaN = sann NaN er NaN = sann

4. Produksjon av operasjoner NaN

Mens du gjør operasjoner som involverer flyte og dobbelt typer, må vi være klar over NaN verdier.

Noen flytende punktmetoder og operasjoner produserer NaN verdier i stedet for å kaste en Unntak. Vi må kanskje håndtere slike resultater eksplisitt.

En vanlig sak som resulterer i ikke-tallverdier er matematiske udefinerte numeriske operasjoner:

dobbelt NULL = 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)); 

Disse eksemplene resulterer i følgende utdata:

ZERO / ZERO = NaN INFINITY - INFINITY = NaN INFINITY * ZERO = NaN 

Numeriske operasjoner som ikke gir resultater i reelle tall, produserer også NaN:

System.out.println ("SQUARE ROOT OF -1 =" + Math.sqrt (-1)); System.out.println ("LOGG PÅ -1 =" + Math.log (-1)); 

Disse uttalelsene vil resultere i:

Kvadratrot av -1 = NaN LOGG AV -1 = NaN 

Alle numeriske operasjoner med NaN som en operandprodukt NaN som et resultat:

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)); 

Og resultatet av det ovennevnte er:

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

Endelig kan vi ikke tildele null til dobbelt eller flyte type variabler. I stedet kan vi eksplisitt tildele NaN til slike variabler for å indikere manglende eller ukjente verdier:

dobbel maxValue = Double.NaN;

5. Konklusjon

I denne artikkelen diskuterte vi NaN og de forskjellige operasjonene som involverer den. Vi diskuterte også behovet for å håndtere NaN mens du gjør flytende beregninger i Java eksplisitt.

Hele kildekoden finner du på GitHub.