简体   繁体   English

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

[英]Strange behavior using high number value in Javascript

Just some days ago, I start to write a wrapper to consume an Brazilian Service when I want to send the "product_code" as an number value, but the number is very high. 就在几天前,当我想将“ product_code”作为数字值发送时,我开始写一个包装来使用巴西服务,但是这个数字非常高。 The magic number is 5213372036854743040, this is a high value, but when I receive my first bug saying to me the product is now available for me, I open some support tickets, but the strange is the POSTMan works great, but in my app using Request I ever receive the error message. 不可思议的数字是5213372036854743040,这是一个很高的值,但是当我收到我的第一个错误消息时,我现在可以使用该产品,我打开了一些支持通知单,但奇怪的是POSTMan的效果很好,但是在我的应用程序中使用请求我曾经收到错误消息。

Well, open the Node.js console and Chrome's console and put the number 5213372036854743040 the return value is just 5213372036854743000. My first thinking is "well, maybe this number is the max number value" but, the max integer in x64 is 9,223,372,036,854,775,807 and the Number.MAX_VALUE is 1.7976931348623157e+308. 好吧,打开Node.js控制台和Chrome控制台,然后将数字5213372036854743040的返回值设为5213372036854743000。我的第一个想法是“好吧,也许这个数字是最大数值”,但是x64中的最大整数是9,223,372,036,854,775,807, Number.MAX_VALUE为1.7976931348623157e + 308。

If I sum the number with 100 the return is the same, but if I double the value this works. 如果我将数字与100相加,则返回的结果相同,但是如果我将该值加倍,则该方法有效。 I think maybe when we got a number with more than 19 algarisms the v8 just round the value to end 000. 我想也许是当我们获得的数字中有超过19种算法时,v8会将值四舍五入到000。

Someone here knows what or because this works with this behavior? 这里的某人知道什么或因为这种行为有效?

Number.MAX_VALUE is the maximum value a floating point number can have. Number.MAX_VALUE是浮点数可以具有的最大值。 For consecutive integers , you want to check Number.MAX_SAFE_INTEGER. 对于连续的整数 ,您要检查Number.MAX_SAFE_INTEGER。

Number.MAX_SAFE_INTEGER > 5213372036854743000; //false

Or perhaps more succinctly: 或更简洁地说:

Number.isSafeInteger(5213372036854743000); //false

Note that both Number.MAX_SAFE_INTEGER and Number.isSafeInteger() are new in ES 2015 and may not be available in old versions of Node. 请注意, Number.MAX_SAFE_INTEGERNumber.isSafeInteger()在ES 2015中都是新的,并且在旧版本的Node中可能不可用。

A good explanation about safe integers is in MDN docs for Number.MAX_SAFE_INTEGER : 关于安全整数的一个很好的解释是在Number.MAX_SAFE_INTEGER MDN文档中

The MAX_SAFE_INTEGER constant has a value of 9007199254740991. The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between -(253 - 1) and 253 - 1. MAX_SAFE_INTEGER常数的值为9007199254740991。该数字背后的原因是,JavaScript使用IEEE 754中指定的双精度浮点格式数字,并且只能安全地表示-(253-1)和253-1之间的数字。

Safe in this context refers to the ability to represent integers exactly and to correctly compare them. 在此上下文中,安全是指能够精确表示整数并正确比较它们的能力。 For example, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 will evaluate to true, which is mathematically incorrect. 例如,Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2将计算为true,这在数学上是不正确的。 See Number.isSafeInteger() for more information. 有关更多信息,请参见Number.isSafeInteger()。

Because MAX_SAFE_INTEGER is a static property of Number, you always use it as Number.MAX_SAFE_INTEGER, rather than as a property of a Number object you created. 因为MAX_SAFE_INTEGER是Number的静态属性,所以您始终将其用作Number.MAX_SAFE_INTEGER,而不是用作创建的Number对象的属性。

Since you are using Node.js, you may be able to get around this using an npm package like bignum . 由于您使用的是Node.js,因此您可以使用bignum之类的npm包解决此问题。

This is how it works unfortunately. 不幸的是,这就是它的工作方式。

See this article -> Double-precision floating-point format 参见本文-> 双精度浮点格式

The format is written with the significand having an implicit integer bit of value 1 (except for special datums, see the exponent encoding below). 格式使用具有1的隐式整数位的有效位写(特殊数据除外,请参见下面的指数编码)。 With the 52 bits of the fraction significand appearing in the memory format, the total precision is therefore 53 bits (approximately 16 decimal digits, 53 log10(2) ≈ 15.955). 由于52位有效分数以内存格式显示,因此总精度为53位(大约16个十进制数字,即53 log10(2)≈15.955)。 The bits are laid out as follows: 这些位的布局如下:

This means that you only have 16 digits to work with to precision. 这意味着您只能精确使用16位数字。 The remainder of the 64 bits are reserved for the exponent. 64位的其余部分保留用于指数。

Example in chrome console :: chrome控制台中的示例::

>9999999999999998

9999999999999998 9999999999999998

>9999999999999999

10000000000000000 10000000000000000

There are a few resources in dealing with large integers in Javascript. 有一些资源可以处理Java中的大整数。 Here is one -> Long Numbers - Adding 这是一个-> 长号-加法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM