NaN di Jawa

1. Gambaran keseluruhan

Sederhananya, NaN adalah nilai jenis data berangka yang bermaksud "bukan nombor".

Dalam tutorial ringkas ini, kami akan menerangkan nilai NaN di Java dan pelbagai operasi yang dapat menghasilkan atau melibatkan nilai ini.

2. Apa itu NaN ?

NaN biasanya menunjukkan hasil operasi yang tidak sah. Sebagai contoh, percubaan membahagikan sifar dengan sifar adalah satu operasi seperti itu.

Kami juga menggunakan NaN untuk nilai yang tidak dapat direpresentasikan. Akar kuasa dua -1 adalah satu kes seperti itu, kerana kita dapat menggambarkan nilai ( i ) hanya dalam bilangan kompleks.

Piawai IEEE untuk Aritmetik Titik Terapung (IEEE 754) menentukan nilai NaN . Di Jawa, jenis titik terapung mengapung dan menerapkan dua kali ganda standard ini.

Java mentakrifkan pemalar NaN dari kedua - dua jenis float dan double sebagai Float .NaN dan Double.NaN :

" Pemalar yang memegang nilai Not-a-Number (NaN) jenis ganda. Ia setara dengan nilai yang dikembalikan oleh Double.longBitsToDouble (0x7ff8000000000000L). "

dan:

"Tetap yang memegang nilai Not-a-Number (NaN) jenis apungan. Ia setara dengan nilai yang dikembalikan oleh Float.intBitsToFloat (0x7fc00000). "

Kami tidak mempunyai jenis pemalar ini untuk jenis data berangka lain di Java.

3. Perbandingan dengan NaN

Semasa menulis kaedah di Java, kita harus memeriksa apakah inputnya valid dan dalam jangkauan yang diharapkan. Nilai NaN bukan input yang sah dalam kebanyakan kes. Oleh itu, kita harus mengesahkan bahawa nilai input bukan nilai NaN dan menangani nilai input ini dengan tepat.

NaN tidak dapat dibandingkan dengan nilai jenis terapung. Ini bermaksud bahawa kita akan salah untuk semua operasi perbandingan yang melibatkan NaN (kecuali “! =” Yang mana kita menjadi kenyataan ).

Kami menjadi kenyataan untuk " x! = X" jika dan hanya jika x adalah NaN:

System.out.println("NaN == 1 = " + (NAN == 1)); System.out.println("NaN > 1 = " + (NAN > 1)); System.out.println("NaN < 1 = " + (NAN  NaN = " + (NAN > NAN)); System.out.println("NaN < NaN = " + (NAN < NAN)); System.out.println("NaN != NaN = " + (NAN != NAN)); 

Mari lihat hasil menjalankan kod di atas:

NaN == 1 = false NaN > 1 = false NaN  NaN = false NaN < NaN = false NaN != NaN = true 

Oleh itu, kita tidak dapat memeriksa NaN dengan membandingkan dengan NaN menggunakan “==” atau “! =“. Sebenarnya, kita jarang menggunakan operator “==” atau “! =” Dengan jenis apungan atau berganda .

Sebagai gantinya, kita dapat menggunakan ungkapan “ x! = x ” . Ungkapan ini menjadi kenyataan hanya untuk NAN.

Kita juga boleh menggunakan kaedah Float.isNaN dan Double.isNaN untuk memeriksa nilai-nilai ini . Ini adalah pendekatan yang disukai kerana lebih mudah dibaca dan difahami:

double x = 1; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x))); x = Double.NaN; System.out.println(x + " is NaN = " + (x != x)); System.out.println(x + " is NaN = " + (Double.isNaN(x))); 

Kami akan mendapat hasil berikut semasa menjalankan kod ini:

1.0 is NaN = false 1.0 is NaN = false NaN is NaN = true NaN is NaN = true

4. Operasi Menghasilkan NaN

Semasa melakukan operasi yang melibatkan jenis apungan dan berganda , kita perlu menyedari nilai NaN .

Beberapa kaedah dan operasi titik terapung menghasilkan nilai NaN dan bukannya membuang Pengecualian. Kita mungkin perlu menangani keputusan tersebut secara eksplisit.

Kes biasa yang menghasilkan nilai not-a-number adalah operasi numerik yang tidak ditentukan secara matematik :

double ZERO = 0; System.out.println("ZERO / ZERO = " + (ZERO / ZERO)); System.out.println("INFINITY - INFINITY = " + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY)); System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO)); 

Contoh-contoh ini menghasilkan output berikut:

ZERO / ZERO = NaN INFINITY - INFINITY = NaN INFINITY * ZERO = NaN 

Operasi berangka yang tidak menghasilkan hasil dalam jumlah nyata juga menghasilkan NaN:

System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1)); System.out.println("LOG OF -1 = " + Math.log(-1)); 

Penyataan ini akan menghasilkan:

SQUARE ROOT OF -1 = NaN LOG OF -1 = NaN 

Semua operasi berangka dengan NaN sebagai operan menghasilkan NaN sebagai hasilnya:

System.out.println("2 + NaN = " + (2 + Double.NaN)); System.out.println("2 - NaN = " + (2 - Double.NaN)); System.out.println("2 * NaN = " + (2 * Double.NaN)); System.out.println("2 / NaN = " + (2 / Double.NaN)); 

Dan hasil perkara di atas adalah:

2 + NaN = NaN 2 - NaN = NaN 2 * NaN = NaN 2 / NaN = NaN 

Akhirnya, kita tidak dapat menetapkan pemboleh ubah jenis nol hingga berganda atau terapung . Sebagai gantinya, kami secara eksplisit memberikan NaN kepada pemboleh ubah tersebut untuk menunjukkan nilai yang hilang atau tidak diketahui:

double maxValue = Double.NaN;

5. Kesimpulan

Dalam artikel ini, kami membincangkan NaN dan pelbagai operasi yang melibatkannya. Kami juga membincangkan keperluan menangani NaN semasa melakukan pengiraan titik apungan di Java secara eksplisit.

Kod sumber lengkap boleh didapati di GitHub.