Saya adalah anggota komite IEEE-754, saya akan mencoba sedikit membantu memperjelas hal-hal.
Pertama, bilangan floating-point bukan bilangan real, dan aritmatika floating-point tidak memenuhi aksioma aritmatika nyata. Trikotomi bukan satu-satunya properti aritmatika nyata yang tidak berlaku untuk mengapung, atau bahkan yang paling penting. Sebagai contoh:
- Selain itu tidak asosiatif.
- Hukum distributif tidak berlaku.
- Ada angka floating-point tanpa invers.
Saya bisa melanjutkan. Tidak mungkin untuk menentukan tipe aritmatika ukuran tetap yang memenuhi semua sifat aritmatika nyata yang kita kenal dan sukai. Komite 754 harus memutuskan untuk membengkokkan atau menghancurkan beberapa dari mereka. Ini dipandu oleh beberapa prinsip sederhana:
- Ketika kami bisa, kami mencocokkan perilaku aritmatika nyata.
- Ketika kami tidak bisa, kami mencoba membuat pelanggaran itu dapat diprediksi dan semudah mungkin untuk didiagnosis.
Mengenai komentar Anda "itu tidak berarti bahwa jawaban yang benar salah", ini salah. Predikat (y < x)
bertanya apakah y
kurang dari x
. Jika y
NaN, maka itu tidak kurang dari nilai floating-point x
, jadi jawabannya tentu salah.
Saya menyebutkan bahwa trikotomi tidak berlaku untuk nilai floating-point. Namun, ada properti serupa yang memang tahan. Klausul 5.11, paragraf 2 dari standar 754-2008:
Empat hubungan yang saling eksklusif dimungkinkan: kurang dari, sama, lebih besar dari, dan tidak teratur. Kasus terakhir muncul ketika setidaknya satu operan adalah NaN. Setiap NaN harus membandingkan unordered dengan segala sesuatu, termasuk dirinya sendiri.
Sejauh menulis kode tambahan untuk menangani NaN berjalan, biasanya mungkin (walaupun tidak selalu mudah) untuk menyusun kode Anda sedemikian rupa sehingga NaN dapat lolos dengan benar, tetapi hal ini tidak selalu terjadi. Ketika tidak, beberapa kode tambahan mungkin diperlukan, tetapi itu adalah harga kecil untuk membayar kenyamanan yang diakibatkan oleh penutupan aljabar ke aritmatika titik-mengambang.
Tambahan: Banyak komentator berpendapat bahwa akan lebih berguna untuk menjaga refleksivitas kesetaraan dan trikotomi dengan alasan mengadopsi NaN! = NaN tampaknya tidak mempertahankan aksioma yang sudah dikenal. Saya mengaku memiliki simpati untuk sudut pandang ini, jadi saya pikir saya akan meninjau kembali jawaban ini dan memberikan sedikit konteks.
Pemahaman saya dari berbicara dengan Kahan adalah bahwa NaN! = NaN berasal dari dua pertimbangan pragmatis:
Itu x == y
harus setara dengan x - y == 0
bila memungkinkan (di luar menjadi teorema aritmatika nyata, ini membuat implementasi perangkat keras perbandingan lebih hemat ruang, yang paling penting pada saat standar dikembangkan - namun, perhatikan bahwa ini dilanggar untuk x = y = tak terhingga, jadi itu bukan alasan yang bagus; itu bisa dibengkokkan dengan wajar (x - y == 0) or (x and y are both NaN)
).
Lebih penting lagi, tidak ada isnan( )
predikat pada saat itu NaN diformalkan dalam aritmatika 8087; itu perlu untuk menyediakan programmer dengan cara yang mudah dan efisien untuk mendeteksi nilai-nilai NaN yang tidak bergantung pada bahasa pemrograman menyediakan sesuatu seperti isnan( )
yang bisa memakan waktu bertahun-tahun. Saya akan mengutip tulisan Kahan sendiri tentang masalah ini:
Jika tidak ada cara untuk menyingkirkan NaNs, mereka akan menjadi tidak berguna seperti orang Indefinisi pada CRAYs; segera setelah seseorang ditemui, perhitungan akan lebih baik dihentikan daripada dilanjutkan untuk waktu yang tidak terbatas hingga kesimpulan yang tidak terbatas. Itulah sebabnya beberapa operasi pada NaN harus memberikan hasil non-NaN. Operasi yang mana? ... Pengecualiannya adalah predikat C “x == x” dan “x! = X”, yang masing-masing 1 dan 0 untuk setiap angka tak terbatas atau terbatas x tetapi terbalik jika x bukan Angka (NaN); ini memberikan satu-satunya perbedaan sederhana antara NaN dan angka dalam bahasa yang tidak memiliki kata untuk NaN dan predikat IsNaN (x).
Perhatikan bahwa ini juga logika yang mengesampingkan pengembalian sesuatu seperti "Tidak-Boolean". Mungkin pragmatisme ini salah tempat, dan standar seharusnya diperlukan isnan( )
, tetapi itu akan membuat NaN hampir mustahil untuk digunakan secara efisien dan nyaman selama beberapa tahun sementara dunia menunggu adopsi bahasa pemrograman. Saya tidak yakin itu akan menjadi tradeoff yang masuk akal.
Terus terang: hasil NaN == NaN tidak akan berubah sekarang. Lebih baik belajar hidup dengannya daripada mengeluh di internet. Jika Anda ingin berdebat bahwa relasi pesanan yang cocok untuk wadah juga harus ada, saya akan merekomendasikan menganjurkan bahwa bahasa pemrograman favorit Anda menerapkan totalOrder
predikat standar di IEEE-754 (2008). Fakta bahwa itu belum berbicara tentang validitas perhatian Kahan yang memotivasi keadaan saat ini.
while (fabs(x - oldX) > threshold)
, keluar dari loop jika konvergensi terjadi atau NaN memasuki perhitungan. Deteksi NaN dan obat yang sesuai kemudian akan terjadi di luar loop.