在Javascript中使用高数值的奇怪行为

时间:2015-09-27 04:21:46

标签: javascript node.js numbers

就在几天前,当我想将“product_code”作为数字值发送时,我开始编写一个使用巴西服务的包装器,但数量非常高。 神奇的数字是5213372036854743040,这是一个很高的价值,但当我收到我的第一个bug告诉我产品现在可供我使用时,我打开一些支持票,但奇怪的是POSTMan效果很好,但在我的应用中使用请求我收到错误消息。

好吧,打开Node.js控制台和Chrome的控制台并输入号码5213372036854743040,返回值仅为5213372036854743000.我的第一个想法是“好吧,也许这个数字是最大数值”但是,x64中的最大整数是9,223,372,036,854,775,807和Number.MAX_VALUE是1.7976931348623157e + 308。

如果我将数字与100相加,则返回值相同,但如果我将该值加倍,则此方法有效。我想也许当我们得到一个超过19个algarisms的数字时,v8只是将值舍入到000结束。

有人在这里知道什么或因为这种行为有效吗?

2 个答案:

答案 0 :(得分:6)

Number.MAX_VALUE是浮点数可以拥有的最大值。对于连续的整数,您要检查Number.MAX_SAFE_INTEGER。

Number.MAX_SAFE_INTEGER > 5213372036854743000; //false

或许更简洁:

Number.isSafeInteger(5213372036854743000); //false

请注意,Number.MAX_SAFE_INTEGERNumber.isSafeInteger()都是ES 2015中的新功能,可能在旧版本的Node中不可用。

关于安全整数的一个很好的解释是MDN docs for Number.MAX_SAFE_INTEGER

  

MAX_SAFE_INTEGER常量的值为9007199254740991.该数字背后的原因是JavaScript使用IEEE 754中规定的双精度浮点格式数字,并且只能安全地表示 - (253 - 1)和253之间的数字 - 1。

     

此上下文中的安全性是指能够准确表示整数并正确比较它们的能力。例如,Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2将评估为true,这在数学上是不正确的。有关更多信息,请参见Number.isSafeInteger()。

     

因为MAX_SAFE_INTEGER是Number的静态属性,所以始终将其用作Number.MAX_SAFE_INTEGER,而不是您创建的Number对象的属性。

由于您使用的是Node.js,因此您可以使用像bignum这样的npm包来解决这个问题。

答案 1 :(得分:0)

不幸的是,这是如何运作的。

查看此文章 - > Double-precision floating-point format

  

使用带有隐式整数的有效数字编写格式   值为1的位(特殊基准除外,请参见指数编码   下面)。随着分数有效数的52位出现在   因此,存储器格式的总精度为53位(约为   16位十进制数,53 log10(2)≈15.955)。这些位被布置为   如下:

这意味着您只有16位数才能达到精确度。 64位的其余部分保留给指数。

chrome console ::

中的示例
>9999999999999998
  

9999999999999998

>9999999999999999
  

10000000000000000

在Javascript中处理大整数有一些资源。这是一个 - > Long Numbers - Adding