Pembahagian dengan Nol di Jawa: Pengecualian, Infiniti, atau Bukan Nombor

1. Gambaran keseluruhan

Membahagi dengan sifar adalah operasi yang tidak mempunyai arti dalam aritmetik biasa dan, oleh itu, tidak ditentukan. Namun, dalam pengaturcaraan, walaupun sering dikaitkan dengan kesalahan, ini tidak selalu berlaku .

Dalam artikel ini, kita akan membahas apa yang berlaku apabila pembahagian dengan sifar terjadi dalam program Java.

Menurut spesifikasi Java operasi pembagian, kita dapat mengenal pasti dua kes pembahagian yang berbeza dengan sifar: bilangan bulat dan nombor titik terapung.

2. Bilangan bulat

Pertama, untuk bilangan bulat, perkara cukup mudah. Membahagi bilangan bulat dengan sifar akan menghasilkan ArithmeticException :

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

3. Jenis Titik Terapung

Namun, ketika berurusan dengan angka floating-point , pengecualian tidak akan dilemparkan :

assertDoesNotThrow(() -> { float result = 12f / 0; });

Untuk menangani kes seperti ini, Java menggunakan beberapa nilai numerik khas yang dapat mewakili hasil operasi tersebut: NaN , POSITIVE_INFINITY , dan NEGATIVE_INFINITY.

3.1. NaN

Mari mulakan dengan membahagikan nilai sifar floating-point dengan sifar :

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

Hasil dalam kes-kes ini adalah NaN (bukan nombor).

3.2. Infiniti

Seterusnya, mari bahagikan beberapa nilai bukan sifar dengan sifar :

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

Seperti yang kita lihat, hasilnya adalah INFINITY, dengan tanda bergantung pada tanda operan.

Selain itu, kita juga boleh menggunakan konsep sifar negatif untuk menuju ke NEGATIVE_INFINITY :

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

3.3. Perwakilan Ingatan

Jadi, mengapa pembahagian integer dengan sifar membuang pengecualian, sedangkan pembahagian titik terapung dengan sifar tidak?

Mari kita perhatikan ini dari perspektif perwakilan memori. Untuk bilangan bulat, tidak ada corak bit yang dapat digunakan untuk menyimpan hasil operasi seperti itu, sementara angka titik terapung memiliki nilai seperti NaN atau INFINITY untuk digunakan dalam kes seperti ini.

Sekarang, mari kita pertimbangkan perwakilan binari pelampung sebagai S EEEEEEEE E FFFFFFF FFFFFFFF FFFFFFFF dengan satu bit (S) untuk tanda, 8 bit (E) untuk eksponen, dan selebihnya (F) untuk mantissa.

Dalam setiap tiga nilai NaN , POSITIVE_INFINITY, dan NEGATIVE_INFINITY, semua bit di bahagian eksponen ditetapkan ke 1.

INFINITY mempunyai bit mantissa diatur ke 0, sementara NaN mempunyai mantissa bukan sifar:

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. Ringkasan

Sebagai kesimpulan, dalam artikel ini kita melihat bagaimana pembahagian dengan sifar berfungsi di Java.

Nilai seperti INFINITY dan NaN tersedia untuk nombor titik terapung tetapi bukan untuk bilangan bulat . Akibatnya, membahagi bilangan bulat dengan sifar akan menghasilkan pengecualian. Namun, untuk float atau double , Java membenarkan operasi.

Kod lengkap boleh didapati di GitHub.