A Java nyelven a „NaN” a „Not a Number” rövidítése. Ez nem kivétel, hanem meglepő módon a NaN adattípusa is egy szám. De gyakran amikor a kezdő programozók véletlenül megkapják, tovább használják a számításaik során. Ezért a Java-ban nem kompatibilis adattípusok együttes használatuk esetén dobható hibát okozhatnak. Az is gyakran látható, hogy
java.lang.ArithmeticException: / by zero
azonosnak tekintik a NaN-val. A Java azonban mindkettőt eltérően kezeli. Elég rejtélyes? Az átfogó megértés érdekében boncolgatjuk, miben különböznek ezek egymástól. A cikk végére megismerheti azokat a lehetséges műveleteket, amelyek nem számot (nan) hoznak létre, és néhány egyszerű kezelési módot.
Mi az a NaN?
Szóval, mi az a NaN? A „NaN”, ahogyan azt sokan sejtitek, a „Not a Number” kifejezést jelenti a Java nyelven. Ez egy speciális lebegőpontos érték a túlcsordulások és hibák jelzésére. Akkor jön létre, amikor egy lebegőpontos számot elosztunk nullával, vagy ha egy negatív szám négyzetgyökét számítjuk ki. Például nézze meg a következő részletet.
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
}
}
Kimenet
NaN
NaN
NaN
A fenti részletben megfigyelhető, hogy a NaN 3 egyszerű művelet eredményeként keletkezik:
- Nulla elosztása
float / double
nullával. - Negatív szám gyökér alatti felvétele (Math.sqrt(-x)). A matematikában egy negatív szám négyzetgyökének felvétele egy képzeletbeli számot eredményez . Ezt az esetet a NaN visszaadásával kezelik Java nyelven.
- Ha egy számot nullával veszünk, akkor az érték nullával való elosztása után a maradékot adja vissza. Ezért a NaN visszaadásra kerül.
Miben különbözik a NaN a pozitív és a negatív végtelentől?
Az IEEE 754 specifikáció szerint három speciális lebegőpontos és dupla érték létezik a határesetek kezelésére:- Pozitív végtelen
- Negatív végtelen
- NaN
Mi az a NaN() módszer?
isNaN()
a Java egyik alapvető módszere annak ellenőrzésére, hogy NaN-értékről van-e szó vagy sem. Ahogy fentebb három esetet tárgyaltunk, ideje tesztelni, hogy az isNaN() metódus hogyan tesz különbséget a +infinity , -infinity és a NaN értékek között.
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());
}
}
Kimenet
+Infinity.IsNaN() = false
-Infinity.IsNaN() = false
NaN.IsNaN() = true
Hogyan hasonlítsuk össze a NaN értékeket?
Minden NaN értéket különállónak tekintünk. Ez azt jelenti, hogy egyetlen NaN sem egyenlő más NaN-lel. Ezen elv szerint, ha egy értéket a másikhoz hasonlítunk, az eredmény mindig negatív. Mivel a NaN rendezetlen, így a numerikus összehasonlítás akár egyetlen NaN-t is hamis eredményt ad. A Java mindkét osztályban biztosítja a Float.NaN és a Double.NaN konstans mezőit az összehasonlítások elvégzéséhez. Ezeket két külön forgatókönyv szerint különböztethetjük meg:- Igaz: Csak egyenlőtlenség esetén (!=)
- Hamis: Minden összehasonlító operandushoz (==, <=, >=, <, >)
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
}
}
Hogyan lehet NaN értékeket generálni?
Mielőtt befejezné, nézzünk meg néhány gyakori példát a Nem szám (nan) megszerzésére.
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));
}
}
Kimenet:
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
GO TO FULL VERSION