Saya baru saja mempelajari pertanyaan OCPJP dan saya menemukan kode aneh ini:
public static void main(String a[]) {
System.out.println(Double.NaN==Double.NaN);
System.out.println(Double.NaN!=Double.NaN);
}
Ketika saya menjalankan kode, saya mendapat:
false
true
Bagaimana hasilnya false
ketika kita membandingkan dua hal yang terlihat sama satu sama lain? Apa NaN
artinya
In [1]: NaN==NaN Out[1]: False
Double.NaN==Double.NaN
memang harus mengembalikan true jikaDouble.NaN
bertipejava.lang.Double
. Namun, tipenya adalah primitifdouble
, dan aturan operator untukdouble
diterapkan (yang menuntut ketidaksetaraan ini untuk kesesuaian dengan IEEE 754, seperti yang dijelaskan dalam jawaban).Jawaban:
NaN berarti "Bukan Angka".
Spesifikasi Bahasa Jawa (JLS) Edisi Ketiga mengatakan :
sumber
false
. Sehingga standar berbeda dari Jawa dalam IEEE menuntut itu(NAN != NAN) == false
.NaN secara definisi tidak sama dengan angka apa pun termasuk NaN. Ini adalah bagian dari standar IEEE 754 dan diimplementasikan oleh CPU / FPU. Ini bukan sesuatu yang JVM harus tambahkan logika untuk mendukung.
http://en.wikipedia.org/wiki/NaN
Java memperlakukan semua NaN sebagai NaN yang senyap.
sumber
Kenapa logika itu
NaN
berartiNot a Number
. Apa yang bukan angka? Apa pun. Anda dapat memiliki apa pun di satu sisi dan apa pun di sisi lain, jadi tidak ada yang menjamin keduanya sama.NaN
dihitung denganDouble.longBitsToDouble(0x7ff8000000000000L)
dan seperti yang Anda lihat dalam dokumentasilongBitsToDouble
:Juga,
NaN
diperlakukan secara logis di dalam API.Dokumentasi
By the way,
NaN
yang diuji sebagai sampel kode Anda:Larutan
Yang bisa Anda lakukan adalah menggunakan
compare
/compareTo
:Atau,
equals
:sumber
NaN != NaN
kesalahan akan membuat program lebih rumit daripadaNaN != NaN
benar? Saya tahu IEEE membuat keputusan bertahun-tahun yang lalu, tetapi dari sudut pandang praktis, saya belum pernah melihat kasus yang bermanfaat. Jika suatu operasi seharusnya berjalan sampai iterasi berturut-turut menghasilkan hasil yang sama, memiliki dua iterasi berturut-turut menghasilkan NaN akan "terdeteksi secara alami" sebagai kondisi keluar jika bukan karena perilaku itu.f(f(f...f(x)))
, dan seseorang menemukany=f[n](x)
untuk beberapan
sehingga hasilf(y)
tidak dapat dibedakan dariy
, makay
akan dapat dibedakan dari hasil yang lebih mendalamf(f(f(...f(y)))
. Bahkan jika seseorang inginNaN==NaN
menjadi salah, memilikiNan!=Nan
juga salah akan kurang "mengejutkan" daripadax!=x
berlaku untuk beberapa x.Double.NaN
tidakDouble
, tapidouble
, jadi pertanyaannya adalah yang terkait dengan perilakudouble
. Meskipun ada fungsi yang dapat menguji untuk hubungan kesetaraan yang melibatkandouble
nilai - nilai, satu-satunya jawaban menarik yang saya tahu untuk "mengapa" (yang merupakan bagian dari pertanyaan awal) adalah "karena beberapa orang di IEEE tidak berpikir pengujian kesetaraan seharusnya mendefinisikan hubungan kesetaraan ". BTW, adakah cara idiomatis ringkas untuk mengujix
dany
untuk kesetaraan hanya menggunakan operator primitif? Semua formulasi yang saya tahu agak kikuk.Itu mungkin bukan jawaban langsung untuk pertanyaan itu. Tetapi jika Anda ingin memeriksa apakah ada sesuatu yang sama dengan
Double.NaN
Anda, Anda harus menggunakan ini:Ini akan kembali
true
sumber
The javadoc untuk Double.NaN mengatakan itu semua:
Menariknya, sumber untuk
Double
mendefinisikan sebagaiNaN
berikut:Perilaku khusus yang Anda gambarkan adalah terprogram ke dalam JVM.
sumber
sesuai, Standar IEEE untuk aritmatika titik apung untuk angka Presisi Ganda,
dimana,
Yang berarti,
Jika semua
E
bit adalah 1, dan jika ada bit yang bukan nolF
maka angkanyaNaN
.oleh karena itu, antara lain, semua nomor berikut adalah
NaN
,Secara khusus, Anda tidak dapat menguji
untuk memeriksa apakah hasil tertentu sama dengan
Double.NaN
, karena semua nilai "bukan angka" dianggap berbeda. Namun, Anda dapat menggunakanDouble.isNaN
metode ini:sumber
NaN adalah nilai khusus yang menunjukkan "bukan angka"; itu adalah hasil dari operasi aritmatika tertentu yang tidak valid, seperti
sqrt(-1)
, dan memiliki (kadang-kadang mengganggu) properti ituNaN != NaN
.sumber
Bukan angka yang mewakili hasil operasi yang hasilnya tidak dapat diwakili dengan angka. Operasi paling terkenal adalah 0/0, yang hasilnya tidak diketahui.
Untuk alasan ini, NaN tidak sama dengan apa pun (termasuk nilai bukan angka lainnya). Untuk info lebih lanjut, cukup periksa halaman wikipedia: http://en.wikipedia.org/wiki/NaN
sumber
0/0
.0/0
selalu NaN, tapi NaN dapat menjadi hasil dari operasi lain - seperti2+NaN
:an operation that has no mathematically definite result produces NaN
, sesuai jawaban oleh @AdrianMitevMenurut tautan ini , ia memiliki berbagai situasi dan sulit diingat. Beginilah cara saya mengingat dan membedakan mereka.
NaN
berarti "secara matematis tidak terdefinisi" misalnya: "hasil 0 dibagi dengan 0 adalah tidak terdefinisi" dan karena itu tidak terdefinisi, jadi "perbandingan yang terkait dengan undefined tentu saja tidak terdefinisi". Selain itu, ini berfungsi lebih seperti premis matematika. Di sisi lain, baik tak terbatas positif dan negatif sudah ditentukan sebelumnya dan pasti, misalnya "positif atau negatif besar tak terbatas didefinisikan dengan baik secara matematis".sumber