Membaca spesifikasi ECMAScript 5.1 , +0
dan -0
dibedakan.
Lalu mengapa +0 === -0
harus dievaluasi true
?
javascript
Randomblue
sumber
sumber
Object.is
untuk membedakan +0 dan -0Jawaban:
JavaScript menggunakan standar IEEE 754 untuk merepresentasikan angka. Dari Wikipedia :
Artikel tersebut berisi informasi lebih lanjut tentang representasi yang berbeda.
Jadi inilah alasan mengapa, secara teknis, kedua nol harus dibedakan.
Perilaku ini secara eksplisit didefinisikan dalam bagian 11.9.6 , Algoritma Perbandingan Kesetaraan Ketat (penekanan sebagian milik saya):
(Hal yang sama berlaku untuk
+0 == -0
btw.)Tampaknya secara logis untuk memperlakukan
+0
dan-0
setara. Kalau tidak, kita harus mempertimbangkan ini dalam kode kita dan saya, secara pribadi, tidak ingin melakukan itu;)catatan:
ES2015 memperkenalkan metode perbandingan baru
Object.is
,.Object.is
secara eksplisit membedakan antara-0
dan+0
:sumber
1/0 === Infinity; // true
dan1/-0 === -Infinity; // true
.1 === 1
dan+0 === -0
tapi1/+0 !== 1/-0
. Aneh sekali!+0 !== -0
;) Itu benar-benar bisa membuat masalah.0 !== +0
/0 !== -0
, yang memang akan membuat masalah juga!Saya akan menambahkan ini sebagai jawaban karena saya mengabaikan komentar @ user113716.
Anda dapat menguji -0 dengan melakukan ini:
sumber
e±308
, nomor Anda hanya dapat diwakili dalam bentuk denormalized dan implementasi yang berbeda memiliki pendapat berbeda tentang di mana mereka mendukung sama sekali atau tidak. Intinya adalah, pada beberapa mesin dalam beberapa mode floating point nomor Anda direpresentasikan sebagai-0
dan pada yang lain sebagai nomor denormalized0.000000000000001e-308
. Mengapung seperti itu, sangat menyenangkanSaya baru saja menemukan contoh di mana +0 dan -0 berperilaku sangat berbeda:
Hati-hati: walaupun menggunakan Math.round pada angka negatif seperti -0,0001, sebenarnya akan menjadi -0 dan dapat mengacaukan beberapa perhitungan selanjutnya seperti yang ditunjukkan di atas.
Cara cepat dan kotor untuk memperbaikinya adalah dengan melakukan sesuatu seperti:
atau hanya:
Ini mengonversi angka menjadi +0 jika -0.
sumber
Dalam standar IEEE 754 yang digunakan untuk mewakili tipe angka dalam JavaScript, tanda diwakili oleh sedikit (angka 1 menunjukkan angka negatif).
Akibatnya, ada nilai negatif dan positif untuk setiap angka yang dapat diwakili, termasuk
0
.Inilah sebabnya mengapa baik
-0
dan+0
eksis.sumber
Menjawab judul aslinya
Are +0 and -0 the same?
:brainslugs83
(dalam komentar jawaban olehSpudley
) menunjukkan kasus penting di mana +0 dan -0 di JS tidak sama - diimplementasikan sebagai fungsi:Ini akan, selain standar
Math.sign
mengembalikan tanda yang benar dari +0 dan -0.sumber
Ada dua nilai yang mungkin (representasi bit) untuk 0. Ini tidak unik. Terutama dalam angka floating point ini dapat terjadi. Itu karena angka floating point sebenarnya disimpan sebagai semacam rumus.
Integer dapat disimpan dengan cara yang terpisah juga. Anda dapat memiliki nilai numerik dengan bit tanda tambahan, jadi dalam ruang 16 bit, Anda dapat menyimpan nilai integer 15 bit dan bit tanda. Dalam representasi ini, nilai 1000 (hex) dan 0000 keduanya adalah 0, tetapi salah satunya adalah +0 dan yang lainnya adalah -0.
Ini bisa dihindari dengan mengurangi 1 dari nilai integer sehingga berkisar antara -1 hingga -2 ^ 16, tetapi ini akan merepotkan.
Pendekatan yang lebih umum adalah menyimpan bilangan bulat dalam 'dua komplemen', tetapi tampaknya ECMAscript memilih untuk tidak melakukannya. Dalam metode ini angka berkisar dari 0000 hingga 7FFF positif. Angka negatif mulai dari FFFF (-1) hingga 8000.
Tentu saja, aturan yang sama juga berlaku untuk bilangan bulat yang lebih besar, tapi saya tidak ingin F saya usang. ;)
sumber
+0 === -0
agak aneh. Karena sekarang kita punya1 === 1
dan+0 === -0
tapi1/+0 !== 1/-0
...+0 === -0
meskipun representasi sedikit berbeda.Kita dapat menggunakan
Object.is
untuk membedakan +0 dan -0, dan satu hal lagiNaN==NaN
,.sumber
Saya akan menyalahkannya pada metode Perbandingan Kesetaraan Ketat ('==='). Lihatlah bagian 4d
lihat 7.2.13 Perbandingan Kesetaraan Ketat pada spesifikasi
sumber
Wikipedia memiliki artikel yang bagus untuk menjelaskan fenomena ini: http://en.wikipedia.org/wiki/Signed_zero
Singkatnya, itu +0 dan -0 didefinisikan dalam spesifikasi IEEE floating point. Keduanya secara teknis berbeda dari 0 tanpa tanda, yang merupakan bilangan bulat, tetapi dalam praktiknya semuanya bernilai nol, sehingga perbedaannya dapat diabaikan untuk semua tujuan praktis.
sumber