Osztás nullával Java-ban: Kivétel, Végtelen vagy Nem Szám
1. Áttekintés
A nullával osztás olyan művelet, amelynek nincs értelme a hétköznapi számtanban, ezért meghatározatlan. A programozásban viszont közben gyakran hibával társul, ez nem mindig így van.
Ebben a cikkben végigmegyünk mi történik, ha nulla osztás történik Java programban.
Az osztási művelet Java-specifikációja szerint két különféle esetet azonosíthatunk nullával: egész számokat és lebegőpontos számokat.
2. Egész számok
Először is, egész számok esetében a dolgok elég egyértelműek. Ha egy egészet nullával osztunk, akkor egy Számtani kivétel:
assertThrows (ArithmeticException.class, () -> {int eredmény = 12/0;});
assertThrows (ArithmeticException.class, () -> {int eredmény = 0/0;});
3. Lebegőpontos típusok
Azonban amikor foglalkozik lebegőpontos számokkal, kivételt nem dobnak:
assertDoesNotThrow (() -> {float eredmény = 12f / 0;});
Az ilyen esetek kezeléséhez a Java néhány speciális numerikus értéket használ, amelyek képviselhetik egy ilyen művelet eredményeit: NaN, POSITIVE_INFINITY, és NEGATIVE_INFINITY.
3.1. NaN
Kezdjük azzal osztva a lebegőpontos nulla értékeket nullával:
assertEquals (Float.NaN, 0f / 0); assertEquals (Double.NaN, 0d / 0);
Az eredmény ezekben az esetekben az NaN (nem szám).
3.2. végtelenség
Ezután menjünk osszon el néhány nulla értéket nulla értékkel:
assertEquals (Float.POSITIVE_INFINITY, 12f / 0); assertEquals (Dupla.POSITIVE_INFINITY, 12d / 0); assertEquals (Float.NEGATIVE_INFINITY, -12f / 0); assertEquals (Double.NEGATIVE_INFINITY, -12d / 0);
Mint láthatjuk, az eredmény az VÉGTELENSÉG, az operandusok előjelétől függő előjellel.
Sőt, a negatív nulla fogalmát is használhatjuk az eljutáshoz NEGATIVE_INFINITY:
assertEquals (Float.NEGATIVE_INFINITY, 12f / -0f); assertEquals (Double.NEGATIVE_INFINITY, 12f / -0f);
3.3. Memória ábrázolás
Tehát miért vet ki kivételt az egész nullával történő osztás, míg a lebegőpontos nullával való osztás nem?
Nézzük ezt a memória-ábrázolás perspektívájából. Egész számok esetében nincs olyan bitminta, amely felhasználható lenne az eredmény tárolására egy ilyen művelet, miközben a lebegőpontos számok értéke olyan, mint NaN vagy VÉGTELENSÉG ilyen esetekben használható.
Most tekintsük az úszó bináris ábrázolását S EEEEEEE E FFFFFFF FFFFFFFF FFFFFFFF formátumban, egy bit (S) a jelhez, 8 bit (E) a kitevõhöz, a többi (F) pedig a mantissza.
A három érték mindegyikében NaN, POSITIVE_INFINITY, és NEGATIVE_INFINITY, az exponens rész összes bitje 1-re van állítva.
VÉGTELENSÉG a mantissa bitek értéke 0, míg a NaN nem nulla mantissája van:
assertEquals (Float.POSITIVE_INFINITY, Float.intBitsToFloat (0b011111111000000000000000000000000000)); assertEquals (Float.NEGATIVE_INFINITY, Float.intBitsToFloat (0b111111111000000000000000000000000000)); assertEquals (Float.NaN, Float.intBitsToFloat (0b111111111000000100000000000000000000)); assertEquals (Float.NaN, Float.intBitsToFloat (0b11111111100100000011000000000100000));
4. Összefoglalás
Összegezve: ebben a cikkben azt láttuk, hogy a nullával való felosztás hogyan működik a Java-ban.
Az olyan értékek, mint VÉGTELENSÉG és NaN lebegőpontos számokhoz állnak rendelkezésre, egész számokhoz azonban nem. Ennek eredményeként egy egész szám nullával való elosztása kivételt eredményez. Azonban a úszó vagy kettős, A Java lehetővé teszi a műveletet.
A teljes kód elérhető a GitHub oldalon.