NaN Java-ban

1. Áttekintés

Egyszerűen fogalmazva, NaN egy numerikus adattípus-érték, amely „nem szám”.

Ebben a gyors bemutatóban elmagyarázzuk a NaN érték a Java-ban, valamint a különféle műveletek, amelyek ezt az értéket előállíthatják,

2. Mi az NaN?

NaN általában érvénytelen műveletek eredményét jelzi. Például a nulla nullával való elosztásának megkísérlése az egyik ilyen művelet.

Mi is használjuk NaN nem reprezentálható értékekért. A -1 négyzetgyöke egy ilyen eset, mivel leírhatjuk az értéket (én) csak komplex számokban.

Az IEEE lebegőpontos számtani szabvány (IEEE 754) határozza meg a NaN érték. Java-ban a lebegőpontos típusok úszó és kettős alkalmazza ezt a szabványt.

A Java meghatározza NaN konstansai mindkettőnek úszó és kettős típusok Úszó.NaN és Dupla. Nem:

Egy konstans, amely kettős típusú Not-a-Number (NaN) értéket tartalmaz. Ez megegyezik a Double.longBitsToDouble (0x7ff800000000000000L) által visszaadott értékkel. ”

és:

„A konstans, amely egy típusú Not-a-Number (NaN) értéket tartalmaz. Ez egyenértékű a Float.intBitsToFloat (0x7fc00000) által visszaadott értékkel. "

A Java többi numerikus adattípusához nincs ilyen típusú állandónk.

3. Összehasonlítás NaN

A módszerek írása közben Java-ban ellenőriznünk kell, hogy a bemenet érvényes-e és a várt tartományon belül van-e. NaN Az érték a legtöbb esetben nem érvényes bemenet. Ezért ellenőriznünk kell, hogy a bemeneti érték nem a NaN értéket, és megfelelően kezelje ezeket a bemeneti értékeket.

NaN nem lehet összehasonlítani egyetlen lebegő típusú értékkel sem. Ez azt jelenti, hogy megkapjuk hamis minden összehasonlító művelethez NaN (kivéve „! =”, amelyre kapunk igaz).

Kapunk igaz a „x! = x ” ha, és csak akkor ha x van 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)); 

Vessünk egy pillantást a fenti kód futtatásának eredményére:

NaN == 1 = hamis NaN> 1 = hamis NaN NaN = hamis NaN <NaN = hamis NaN! = NaN = igaz 

Ennélfogva, nem ellenőrizhetjük NaN azzal összehasonlítva NaN a „==” vagy a „! =“ használatával. Valójában ritkán kell használnunk „==” vagy „! =” Operátorokat úszó vagy kettős típusok.

Ehelyett használhatjuk a „x != x ”. Ez a kifejezés csak a következőre tér vissza: NAN.

Használhatjuk a módszereket is Float.isNaN és Dupla.isNaN hogy ellenőrizze ezeket az értékeket. Ez az előnyben részesített megközelítés, mivel olvashatóbb és érthetőbb:

kettős x = 1; System.out.println (x + "NaN =" + (x! = X)); System.out.println (x + "NaN =" + (Double.isNaN (x))); x = Dupla, NaN; System.out.println (x + "NaN =" + (x! = X)); System.out.println (x + "NaN =" + (Double.isNaN (x))); 

A kód futtatásakor a következő eredményt kapjuk:

1,0 = NaN = hamis 1,0 = NaN = hamis NaN = NaN = igaz NaN = NaN = igaz

4. Műveletek előállítása NaN

Miközben műveleteket végez úszó és kettős típusúak, tisztában kell lennünk a NaN értékek.

Néhány lebegőpontos módszer és művelet eredményez NaN értékek helyett egy Kivétel. Lehet, hogy kifejezetten kezelnünk kell az ilyen eredményeket.

Gyakori eset, amely nem számértékeket eredményez matematikailag nem definiált numerikus műveletek:

kettős ZERO = 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)); 

Ezek a példák a következő kimenetet eredményezik:

ZERO / ZERO = NaN VÉGTELEN - VÉGTELEN = NaN VÉGTELEN * ZERO = NaN 

Azok a numerikus műveletek is eredményeznek, amelyeknek nincs valós eredménye NaN:

System.out.println ("Négyzetgyök -1 =" + Math.sqrt (-1)); System.out.println ("LOG OF -1 =" + Math.log (-1)); 

Ezek az állítások a következőket eredményezik:

A -1 négyzetgyök = NaN A log = -1 = NaN 

Minden numerikus művelet a NaN mint operandus-produkció NaN ennek eredményeként:

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

És a fentiek eredménye:

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

Végül nem rendelhetünk hozzá nulla nak nek kettős vagy úszó típusú változók. Ehelyett kifejezetten kijelölhetjük NaN az ilyen változókra a hiányzó vagy ismeretlen értékek jelzésére:

dupla maxValue = Dupla.NaN;

5. Következtetés

Ebben a cikkben megvitattuk NaN és a vele járó különféle műveletek. Megbeszéltük a kezelés szükségességét is NaN miközben lebegőpontos számításokat végez Java-ban.

A teljes forráskód megtalálható a GitHub oldalon.