12

我的问题很简单,但我不确定是否有使用 JSON.parse 的“本机”解决方案。

我从 API收到这个字符串:

{ "key" : -922271061845347495 }

当我在这个字符串上使用 JSON.parse 时,它​​变成了这个对象

{ "key" : -922271061845347500 }

如您所见,当数字太长时解析停止(您可以在此处检查此行为)。它只有 15 位精确数字,最后一位是四舍五入的,后面的数字设置为 0。是否有“本机”解决方案来保持精确值?(这是一个ID,所以我不能四舍五入)

我知道我可以使用正则表达式来解决这个问题,但如果它存在,我更喜欢使用“本机”方法。

4

2 回答 2

19

您认为解析在某些数字后停止的假设是不正确的。

在这里说:

在 JavaScript 中,所有数字都是浮点数。JavaScript 使用标准的 8 字节 IEEE 浮点数字格式,这意味着范围是:

±1.7976931348623157 x 10 308 - 非常大,±5 x 10 -324 - 非常小。

由于 JavaScript 使用浮点数,因此只能保证以下整数之间的准确性:-9007199254740992 (-2 53 ) 和 9007199254740992 (2 53 )

您的数字位于“准确”范围之外,因此它被转换为 JavaScript 数字的最接近的表示形式。任何评估此数字的尝试(使用 JSON.parse、eval、parseInt)都会导致数据丢失。因此,我建议您将密钥作为字符串传递。如果您不控制 API,请提交功能请求。

于 2012-05-17T07:23:19.817 回答
4

数字太大而无法正确解析。

一种解决方案是:

  1. 在解析之前从 API 预处理您的字符串以将其转换为字符串。
  2. 预执行正常解析
  3. 或者,您可以出于自己的目的将其转换回数字。

这是将字符串中的所有数字(以 : 开头)转换为字符串的正则表达式:

 // convert all number fields into strings to maintain precision
 // : 922271061845347495, => : "922271061845347495",
 stringFromApi = stringFromApi.replace(/:\s*(-?\d+),/g, ': "$1",');

正则表达式解释:

  • \s* 任意数量的空格
  • -?一个或零个“-”符号(负数支持)
  • \d+ 一位或多位数字
  • (...) 将被放入 $1 变量中
于 2018-09-28T04:34:06.457 回答