javascript如何处理大整数(超过52位)?

时间:2016-07-07 16:44:29

标签: javascript node.js integer

考虑这段代码(node v5.0.0)

const a = Math.pow(2, 53)
const b = Math.pow(2, 53) + 1
const c = Math.pow(2, 53) + 2

console.log(a === b) // true
console.log(a === c) // false

为什么a === b是真的?

javascript可以处理的最大整数值是多少?

我实现了最多2 ^ 64的随机整数生成器。我应该注意哪些陷阱?

5 个答案:

答案 0 :(得分:3)

回答第二个问题,这是JavaScript中的最大安全整数

console.log( Number.MAX_SAFE_INTEGER );

所有其余内容都写在MDN

  

MAX_SAFE_INTEGER常量的值为9007199254740991。该   这个数字背后的推理是JavaScript使用双精度   IEEE 754中指定的浮点格式编号,只能   安全地表示-(2 ** 53 - 1)2 ** 53 - 1之间的数字。

     

此上下文中的安全是指表示整数的能力   准确地并且正确地比较它们。例如,   Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2会   评估为true,这在数学上是不正确的。看到   Number.isSafeInteger()了解更多信息。

答案 1 :(得分:2)

  

javascript如何处理大整数?

JS没有整数。 JS数字是64位浮点数。它们存储为尾数和指数。

精度由尾数给出,大小由指数给出。

如果您的数字需要比尾数中存储的数字更精确,则最低有效位将被截断。

9007199254740992; // 9007199254740992
(9007199254740992).toString(2);
// "100000000000000000000000000000000000000000000000000000"
//  \        \                    ...                   /\
//   1        10                                      53  54
// The 54-th is not stored, but is not a problem because it's 0

9007199254740993; // 9007199254740992
(9007199254740993).toString(2);
// "100000000000000000000000000000000000000000000000000000"
//  \        \                    ...                   /\
//   1        10                                      53  54
// The 54-th bit should be 1, but the mantissa only has 53 bits!

9007199254740994; // 9007199254740994
(9007199254740994).toString(2);
// "100000000000000000000000000000000000000000000000000010"
//  \        \                    ...                   /\
//   1        10                                      53  54
// The 54-th is not stored, but is not a problem because it's 0

然后,您可以存储所有这些整数:

-9007199254740992, -9007199254740991, ..., 9007199254740991, 9007199254740992

第二个称为minimum safe integer

  

Number.MIN_SAFE_INTEGER的值是这样的最小整数n   n和n - 1都可以完全表示为Number值。

     

Number.MIN_SAFE_INTEGER的值是-9007199254740991   ( - (2 53 -1))

第二个被称为maximum safe integer

  

Number.MAX_SAFE_INTEGER的值是这样的最大整数   n和n + 1都可以完全表示为Number值。

     

Number.MAX_SAFE_INTEGER的值为9007199254740991   (2 53 -1)。

答案 2 :(得分:1)

。:: JavaScript仅支持53位整数::。

JavaScript中的所有数字都是浮点数,这意味着整数总是表示为

sign × mantissa × 2exponent

尾数有53位。你可以使用指数来获得更高的整数,但是它们将不再是连续的。例如,您通常需要将尾数乘以2(指数1)以达到第54位。

但是,如果乘以2,则只能表示每二个整数:

Math.pow(2, 53)      // 54 bits 9007199254740992
Math.pow(2, 53) + 1  // 9007199254740992
Math.pow(2, 53) + 2  //9007199254740994
Math.pow(2, 53) + 3  //9007199254740996
Math.pow(2, 53) + 4  //9007199254740996

添加期间的舍入效果会使奇数增量无法预测(+1对+3)。实际表示有点复杂,但这种解释应该有助于您理解基本问题。

您可以安全地使用strint库对字符串中的大整数进行编码,并对它们执行算术运算。

Here是完整的文章。

答案 3 :(得分:0)

{{1}}将告诉您JS实现中可表示的最大浮点值。答案很可能是:1.7976931348623157e + 308。但这并不意味着可以准确表示高达10 ^ 308的每个整数。正如您的示例代码所示,超过2 ^ 53只能表示偶数,当您在数字行上走得更远时,间隙会变得更宽。

如果你需要大于2 ^ 53的精确整数,你可能想要使用bignum包,它允许任意大的整数(在可用内存的范围内)。我碰巧知道的两个包是:

BigInt by Leemon

Crunch

答案 4 :(得分:0)

要补充这里的其他答案,值得一提的是BigInt存在。这使JavaScript可以处理任意大的整数。

在数字上使用n后缀,并使用2n ** 53n + 2n之类的常规运算符。重要的是要指出,BigInt不是数字,但是您可以通过显式转换与数字进行范围限制的互操作。

Node.js REPL上的一些示例:

> 999999999999999999999999999999n + 1n
1000000000000000000000000000000n
> 2n ** 53n
9007199254740992n
> 2n ** 53n + 1n
9007199254740993n
> 2n ** 53n == 2n ** 53n + 1n
false
> typeof 1n
'bigint'
> 3 * 4n
TypeError: Cannot mix BigInt and other types, use explicit conversions
> BigInt(3) * 4n
12n
> 3 * Number(4n)
12
> Number(2n ** 53n) == Number(2n ** 53n + 1n)
true
相关问题