Nombor besar tersilap dibundarkan dalam JavaScript
Isu:
Di bawah dalam kod ini:
var jsonString = '{"id":714341252076979033,"type":"FUZZY"}'; var jsonParsed = JSON.parse(jsonString); console.log(jsonString, jsonParsed);
dalam Firefox Dalam 3.5, nilai jsonParsed ialah nombor bulat:
Object>
Saya mencuba nilai yang berbeza tetapi sentiasa mendapat nombor bulat.
Saya juga tidak faham peraturan pembundarannya. 714341252076979136 dibundarkan kepada 714341252076979200, dan 714341252076979135 dibundarkan kepada 714341252076979100.
Kenapa ni?
Jawapan:
Anda melimpahi kapasiti jenis angka JavaScript, lihat bahagian 8.5 spesifikasi dan Wikipedia pada titik terapung binari berketepatan dua IEEE-754 halaman format untuk butiran. ID ini mestilah rentetan.
Titik terapung berketepatan dua IEEE-754 (jenis nombor yang digunakan oleh JavaScript) tidak boleh mewakili semua nombor dengan tepat (sudah tentu). 0.1 0.2 === 0.3 adalah palsu Ini terkenal. Ini mempengaruhi integer sama seperti ia mempengaruhi pecahan; ia bermula pada 9,007,199,254,740,991 (Number.MAX_SAFE_INTEGER).
Nombor.MAX_SAFE_INTEGER 1 (9007199254740992) melebihi dan format titik terapung IEEE-754 tidak lagi boleh mewakili setiap integer berturut-turut. 9007199254740991 1 ialah 9007199254740992, tetapi 9007199254740992 1 juga ialah 9007199254740992, kerana 9007199254740993 tidak boleh diwakili dalam format ini. Perkara seterusnya yang boleh diwakili ialah 9007199254740994. Kemudian ia tidak boleh mewakili 9007199254740995, tetapi ia boleh mewakili 9007199254740996.
Sebabnya ialah kami kehabisan bit, jadi kami tidak lagi mempunyai bit 1s sekarang mewakili gandaan 2. Akhirnya, jika kita meneruskan, kita akan kehilangan sedikit itu dan hanya berfungsi dalam gandaan 4. Dan seterusnya.
Nilai anda jauh melebihi ambang itu, jadi ia dibundarkan kepada nilai yang boleh diwakili terdekat.
Mulai ES2020, anda boleh menggunakan BigInt untuk mewakili integer besar secara sewenang-wenangnya, tetapi tiada JSON untuk mewakilinya. Anda boleh menggunakan rentetan dan fungsi pemulih:
const jsonString = '{"id":"714341252076979033","type":"FUZZY"}'; // 注意它是一个字符串 -----------^ const obj = JSON.parse(jsonString, (key, value) => { if (key === "id" && typeof value === "string" && value.match(/^\d+$/)) { return BigInt(value); } return value; }); console.log(obj);
(Dilihat dalam konsol sebenar, konsol serpihan tidak memahami BigInt.)
Atas ialah kandungan terperinci Mengapakah nombor besar dibundarkan secara salah dalam penghuraian JSON JavaScript?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!