Maison > interface Web > js tutoriel > Pourquoi les grands nombres sont-ils mal arrondis dans l'analyse JavaScript JSON ?

Pourquoi les grands nombres sont-ils mal arrondis dans l'analyse JavaScript JSON ?

Susan Sarandon
Libérer: 2024-12-20 14:40:13
original
999 Les gens l'ont consulté

Why are large numbers incorrectly rounded in JavaScript JSON parsing?

Les grands nombres sont incorrectement arrondis en JavaScript

Problème :

Ci-dessous Dans ce code :

var jsonString = '{"id":714341252076979033,"type":"FUZZY"}';
var jsonParsed = JSON.parse(jsonString);
console.log(jsonString, jsonParsed);
Copier après la connexion

dans Firefox Dans la version 3.5, la valeur de jsonParsed est un nombre arrondi :

Object>
Copier après la connexion

J'ai essayé différentes valeurs mais j'ai toujours obtenu un nombre arrondi.

Je ne comprends pas non plus ses règles d’arrondi. 714341252076979136 est arrondi à 714341252076979200, et 714341252076979135 est arrondi à 714341252076979100.

Pourquoi ça ?

Réponse :

Vous dépassez la capacité du type numérique JavaScript, voir la section 8.5 de la spécification et Wikipédia sur la virgule flottante binaire double précision IEEE-754 formater la page pour plus de détails. Ces identifiants doivent être des chaînes.

La virgule flottante double précision IEEE-754 (le type de nombre utilisé par JavaScript) ne peut pas représenter exactement tous les nombres (bien sûr). 0,1 0,2 === 0,3 est faux C'est célèbre. Cela affecte les entiers tout comme les fractions ; cela commence à 9 007 199 254 740 991 (Number.MAX_SAFE_INTEGER).

Number.MAX_SAFE_INTEGER 1 (9007199254740992) est dépassé et le format à virgule flottante IEEE-754 ne peut plus représenter chaque entier consécutif. 9007199254740991 1 est 9007199254740992, mais 9007199254740992 1 est également 9007199254740992, car 9007199254740993 ne peut pas être représenté dans ce format. La prochaine chose qui peut être représentée est 9007199254740994. Il ne peut alors pas représenter 9007199254740995, mais il peut représenter 9007199254740996.

La raison est que nous avons manqué de bits, nous n'avons donc plus les bits 1s ; le bit le plus bas représente désormais un multiple de 2. Finalement, si nous continuons, nous perdrons ce peu et ne travaillerons que par multiples de 4. Et ainsi de suite.

Vos valeurs sont bien au-dessus de ce seuil, elles sont donc arrondies à la valeur représentable la plus proche.

À partir d'ES2020, vous pouvez utiliser BigInt pour représenter des entiers arbitrairement grands, mais il n'y a pas de JSON pour les représenter. Vous pouvez utiliser des chaînes et une fonction de restauration :

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);
Copier après la connexion

(Visualisée dans la vraie console, la console fragment ne comprend pas BigInt.)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal