JavaScript で大きな数値が誤って丸められる
問題:
以下 このコード内: Firefox の
var jsonString = '{"id":714341252076979033,"type":"FUZZY"}'; var jsonParsed = JSON.parse(jsonString); console.log(jsonString, jsonParsed);
3.5 では、jsonParsed の値は四捨五入された数値です:
Object>
さまざまな値を試しましたが、常に四捨五入された数値が得られました。
四捨五入のルールも分かりません。 714341252076979136 は 714341252076979200 に四捨五入され、714341252076979135 は 714341252076979100 に四捨五入されます。
これはなぜですか?
答え:
JavaScript 数値型の容量をオーバーしています。IEEE-754 倍精度 2 進浮動小数点については仕様のセクション 8.5 と Wikipedia を参照してください。詳細については、フォーマットのページを参照してください。これらの ID は文字列である必要があります。
IEEE-754 倍精度浮動小数点 (JavaScript で使用される数値型) は、すべての数値を正確に表すことはできません (もちろん)。 0.1 0.2 === 0.3 は偽 これは有名です。これは、分数に影響するのと同様に、整数にも影響します。9,007,199,254,740,991 (Number.MAX_SAFE_INTEGER) から始まります。
Number.MAX_SAFE_INTEGER 1 (9007199254740992) を超えたため、IEEE-754 浮動小数点形式は連続する各整数を表すことができなくなりました。 9007199254740991 1 は 9007199254740992 ですが、9007199254740993 はこの形式では表現できないため、9007199254740992 1 も 9007199254740992 になります。次に表現できるのは 9007199254740994 です。この場合、9007199254740995 は表現できませんが、9007199254740996 は表現できます。
その理由は、ビットが不足したため、1 のビットがなくなり、最下位ビットが 2 の倍数を表すようになりました。このまま続けると、最終的にはその部分が失われ、4 の倍数でしか動作しなくなります。等々。
値はそのしきい値をはるかに上回っているため、最も近い表現可能な値に丸められます。
ES2020 以降、BigInt を使用して任意の大きな整数を表すことができますが、それらを表す JSON はありません。文字列と復元関数を使用できます:
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);
(実際のコンソールで見ると、フラグメント コンソールは BigInt を認識しません。)
以上がJavaScript JSON 解析で大きな数値が誤って丸められるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。