Dalam JavaScript, nilai NaN dapat diwakili oleh berbagai macam 64-bit ganda secara internal. Secara khusus, sembarang ganda dengan representasi bitwise berikut:
x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
Ditafsirkan sebagai NaN. Pertanyaan saya adalah: seandainya saya melemparkan dua uint 32-bit ke Nomor JS menggunakan ArrayBuffers, menyebarkannya, lalu melemparkannya kembali ke dua uint 32-bit. Akankah bit yang dipulihkan sama dengan yang asli, atau apakah mesin JS diizinkan untuk mengubah bit NaN sesuka hati? Dengan kata lain, dapatkah nomor JS digunakan untuk menyimpan 64-bit losslesly?
javascript
ieee-754
Viktor Maia
sumber
sumber
Jawaban:
ECMA-262 Edisi ke 9 , Juni 2018, (standar yang dimaksudkan untuk menyesuaikan JavaScript) mengatakan, dalam 6.1.6 "The Number Type":
24.1.17 "NumberToRawBytes (tipe, nilai, isLittleEndian)" mengatakan:
Saya tidak melihat bagian-bagian lain yang menyebutkan NaN yang menerangi pertanyaan ini. Di satu sisi, 24.1.17 secara efektif memberi tahu kita bahwa bit NaN harus dipertahankan ketika mengubah NaN menjadi byte mentah. Namun, tidak ada hal lain yang memberi tahu kami bahwa bit harus disimpan dalam operasi lain. Orang mungkin menyimpulkan bahwa ini adalah maksudnya, karena persyaratan ini dalam 24.1.17 tidak akan berfungsi jika bit dapat diubah secara sewenang-wenang oleh operasi lainnya. Tapi saya tidak akan bergantung pada implementasi JavaScript untuk mengimplementasikan ini sesuai dengan maksud itu.
sumber
Saya pernah mengajukan pertanyaan untuk Java, tentang ketergantungan perangkat keras terhadap nilai-nilai NaN, dan diketahui bahwa beberapa CPU akan secara diam-diam mengubah "pensinyalan NaN" menjadi "NaN yang tenang" (mengatur bit NaN yang tenang) (mengatur bit NaN yang tenang) ketika nilai NaN dimuat ke dalam register prosesor. Jadi setidaknya salah satu bit, bit NaN yang tenang, tidak dapat Anda gunakan untuk menyimpan data sewenang-wenang.
Menggunakan bit lain, selama bit NaN yang diam diatur, mungkin aman. Tapi sepertinya masih ada ruang untuk implementasi-ketergantungan di sini, dan karenanya tidak ada jaminan.
Masalah semacam ini adalah mengapa operasi bahasa normal menghindari melakukan apa pun yang tergantung pada nilai internal NaN, dan lebih suka memperlakukan semua NaN sebagai "hanya NaN".
sumber
Standar IEEE-754 asli sengaja meninggalkan bit NaN hingga implementasi. Itu memang memberikan petunjuk, seperti
Anda mungkin memasukkan alamat memori asli tempat NaN dibuat.
Sementara itu, aritmatika memiliki aturan khusus tentang apa yang harus dilakukan dengan NaN, dan itu tidak ada hubungannya dengan bit di bagian bawah. Saya tidak berpikir itu bahkan mengatakan apa yang harus dilakukan ketika menambahkan dua NaN - menjaga bit dari salah satu dari mereka dibandingkan membuat satu set bit. Hanya saja hasilnya pasti masih NaN.
sumber