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.