在 Javascript 中使用高数值的奇怪行为
Strange behavior using high number value in Javascript
就在几天前,当我想将 "product_code" 作为数字值发送时,我开始编写包装器来使用巴西服务,但数字非常高。
幻数是 5213372036854743040,这是一个很高的值,但是当我收到第一个错误,告诉我该产品现在可供我使用时,我打开了一些支持票,但奇怪的是 POSTMan 工作得很好,但在我的应用程序中使用请求我曾经收到错误消息。
好吧,打开 Node.js 控制台和 Chrome 的控制台并输入数字 5213372036854743040 return 值就是 5213372036854743000。我的第一个想法是 "well, maybe this number is the max number value" 但是,x64 中的最大整数是 9,223,372,036,854,775,807,Number.MAX_VALUE 是 1.7976931348623157e+308.
如果我将数字与 100 相加,return 是相同的,但如果我将该值加倍,则该值有效。我想也许当我们得到一个包含超过 19 个藻类的数字时,v8 会将值四舍五入到 000 结尾。
这里有人知道什么或者因为这适用于这种行为?
不幸的是,这就是它的工作原理。
查看这篇文章 -> 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). 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). The bits are laid out as
follows:
这意味着您只有 16 位数字可以精确处理。 64 位的其余部分保留给指数。
chrome 控制台中的示例 ::
>9999999999999998
9999999999999998
>9999999999999999
10000000000000000
Javascript 中有一些处理大整数的资源。这是一个 -> Long Numbers - Adding
Number.MAX_VALUE 是 浮点数 的最大值。对于连续的 整数 ,您要检查 Number.MAX_SAFE_INTEGER.
Number.MAX_SAFE_INTEGER > 5213372036854743000; //false
或者更简洁:
Number.isSafeInteger(5213372036854743000); //false
请注意 Number.MAX_SAFE_INTEGER
和 Number.isSafeInteger()
都是 ES 2015 中的新内容,在旧版本的 Node 中可能不可用。
关于安全整数的一个很好的解释在MDN docs for Number.MAX_SAFE_INTEGER
:
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.
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. See Number.isSafeInteger() for more information.
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.
由于您使用的是 Node.js,您可以使用像 bignum.
这样的 npm 包来解决这个问题
就在几天前,当我想将 "product_code" 作为数字值发送时,我开始编写包装器来使用巴西服务,但数字非常高。 幻数是 5213372036854743040,这是一个很高的值,但是当我收到第一个错误,告诉我该产品现在可供我使用时,我打开了一些支持票,但奇怪的是 POSTMan 工作得很好,但在我的应用程序中使用请求我曾经收到错误消息。
好吧,打开 Node.js 控制台和 Chrome 的控制台并输入数字 5213372036854743040 return 值就是 5213372036854743000。我的第一个想法是 "well, maybe this number is the max number value" 但是,x64 中的最大整数是 9,223,372,036,854,775,807,Number.MAX_VALUE 是 1.7976931348623157e+308.
如果我将数字与 100 相加,return 是相同的,但如果我将该值加倍,则该值有效。我想也许当我们得到一个包含超过 19 个藻类的数字时,v8 会将值四舍五入到 000 结尾。
这里有人知道什么或者因为这适用于这种行为?
不幸的是,这就是它的工作原理。
查看这篇文章 -> 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). 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). The bits are laid out as follows:
这意味着您只有 16 位数字可以精确处理。 64 位的其余部分保留给指数。
chrome 控制台中的示例 ::
>9999999999999998
9999999999999998
>9999999999999999
10000000000000000
Javascript 中有一些处理大整数的资源。这是一个 -> Long Numbers - Adding
Number.MAX_VALUE 是 浮点数 的最大值。对于连续的 整数 ,您要检查 Number.MAX_SAFE_INTEGER.
Number.MAX_SAFE_INTEGER > 5213372036854743000; //false
或者更简洁:
Number.isSafeInteger(5213372036854743000); //false
请注意 Number.MAX_SAFE_INTEGER
和 Number.isSafeInteger()
都是 ES 2015 中的新内容,在旧版本的 Node 中可能不可用。
关于安全整数的一个很好的解释在MDN docs for Number.MAX_SAFE_INTEGER
:
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.
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. See Number.isSafeInteger() for more information.
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.
由于您使用的是 Node.js,您可以使用像 bignum.
这样的 npm 包来解决这个问题