Podjela nula u Javi: izuzetak, beskonačnost ili nije broj

1. Pregled

Dijeljenje s nulom je operacija koja nema značenja u uobičajenoj aritmetici i, prema tome, nije definirana. U programiranju, međutim, dok to je često povezan s pogreškom, to nije uvijek slučaj.

U ovom ćemo članku proći što se događa kad se dogodi dijeljenje s nulom u programu Java.

Prema Java specifikaciji operacije dijeljenja, možemo identificirati dva različita slučaja dijeljenja s nulom: cijeli brojevi i brojevi s pomičnom zarezom.

2. Cijeli brojevi

Prvo, kod cijelih brojeva stvari su prilično jednostavne. Dijeljenje cijelog broja s nulom rezultirat će znakom ArithmeticException:

assertThrows (ArithmeticException.class, () -> {int rezultat = 12/0;});
assertThrows (ArithmeticException.class, () -> {int rezultat = 0/0;});

3. Vrste s pomičnom zarezom

Međutim, kad se bave s brojevima s pomičnom zarezom, iznimka se neće izbaciti:

assertDoesNotThrow (() -> {rezultat s pomicanjem = 12f / 0;});

Kako bi riješila slučajeve poput ovih, Java koristi neke posebne numeričke vrijednosti koje mogu predstavljati rezultate takve operacije: NaN, POZITIVNA_BESKRAJNOST, i NEGATIVNA_BESKRAJNOST.

3.1. NaN

Krenimo od dijeljenje nula vrijednosti s pomičnim zarezom s nulom:

assertEquals (Float.NaN, 0f / 0); assertEquals (Double.NaN, 0d / 0);

Rezultat u tim slučajevima je NaN (nije broj).

3.2. Beskonačnost

Dalje, idemo podijeliti neke vrijednosti koje nisu nula s nulom:

assertEquals (Float.POSITIVE_INFINITY, 12f / 0); assertEquals (Double.POSITIVE_INFINITY, 12d / 0); assertEquals (Float.NEGATIVE_INFINITY, -12f / 0); assertEquals (Double.NEGATIVE_INFINITY, -12d / 0);

Kao što vidimo, rezultat je INFINITY, sa predznakom ovisno o predznaku operanda.

Štoviše, također možemo koristiti koncept negativne nule da bismo došli do NEGATIVNA_BESKRAJNOST:

assertEquals (Float.NEGATIVE_INFINITY, 12f / -0f); assertEquals (Double.NEGATIVE_INFINITY, 12f / -0f);

3.3. Predstavljanje memorije

Pa, zašto cjelobrojna podjela s nulom daje iznimku, dok podjela s pomičnom zarezom s nulom ne?

Pogledajmo ovo iz perspektive predstavljanja memorije. Za cijele brojeve ne postoji uzorak bitova koji se može koristiti za pohranu rezultata takve operacije, dok brojevi s pomičnom zarezom imaju vrijednosti poput NaN ili BESKONAČNOST da se koristi u ovakvim slučajevima.

Sada, razmotrimo binarni prikaz plovka kao S EEEEEEE E FFFFFFF FFFFFFFF FFFFFFFF s jednim bitom (S) za znak, 8 bitova (E) za eksponent, a ostatak (F) za mantisu.

U svakoj od tri vrijednosti NaN, POSITIVE_INFINITY, i NEGATIVE_INFINITY, svi bitovi u eksponentnom dijelu postavljeni su na 1.

BESKONAČNOST ima bitove mantise postavljene na 0, dok NaN ima manisu koja nije nula:

assertEquals (Float.POSITIVE_INFINITY, Float.intBitsToFloat (0b01111111100000000000000000000000)); assertEquals (Float.NEGATIVE_INFINITY, Float.intBitsToFloat (0b11111111100000000000000000000000)); assertEquals (Float.NaN, Float.intBitsToFloat (0b11111111100000010000000000000000)); assertEquals (Float.NaN, Float.intBitsToFloat (0b11111111100000011000000000100000));

4. Sažetak

Da sumiramo stvari, u ovom smo članku vidjeli kako podjela s nulom djeluje na Javi.

Vrijednosti poput BESKONAČNOST i NaN dostupni su za brojeve s pomičnom zarezom, ali ne i za cijele brojeve. Kao rezultat, dijeljenje cijelog broja s nulom rezultirat će iznimkom. Međutim, za plutati ili dvostruko, Java dopušta operaciju.

Kompletni kod dostupan je na GitHubu.