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);
dans Firefox Dans la version 3.5, la valeur de jsonParsed est un nombre arrondi :
Object>
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);
(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!