2016-07-07 128 views
1

考虑这个代码(节点V5.0.0)JavaScript如何处理大整数(超过52位)?

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。我应该知道有什么陷阱吗?

+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE –

+0

对不起,已经修复。 – user1518183

+0

a和b是相同的数字,并且相同的数字是相同的或相等的。 – dandavis

回答

1

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

在JavaScript中的所有数字均浮点这意味着整数始终表示为

sign × mantissa × 2exponent 

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

但是,如果乘以二,你只能够代表每秒整数:在添加过程中

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

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

console.log(Number.MAX_SAFE_INTEGER); 

其余全部是写在MDN

MAX_SAFE_INTEGER不断有9007199254740991值。推理该数字的 是JavaScript使用双精度 IEEE 754中指定的浮点格式数字,并且只能使用 安全地表示-(253 - 1)253 - 1之间的数字。

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

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.MIN_SAFE_INTEGER值是-9007199254740991 ( - (2 -1))。

第二最后一个被称为maximum safe integer

Number.MAX_SAFE_INTEGER的值是最大的整数n如 即n和n + 1都精确表示为数字值。

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

0

Number.MAX_VALUE会告诉你在你的JS实现中可表示的最大浮点值。答案可能是:1.7976931348623157e + 308。但这并不意味着每个10^308以下的整数都可以精确表示。正如您的示例代码所示,除了2^53之外,只有偶数可以表示,并且随着您走出数字线,差距会变得更大。

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

BigInt by Leemon

Crunch