如何处理大整数(超过52位)?
考虑这个代码(节点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。 我应该知道有什么陷阱吗?
。:: 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库来对string中的大整数进行编码,并对它们进行算术运算。
这是完整的文章。
回答你的第二个问题,这里是你在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
,这在math上是不正确的。 有关更多信息,请参阅Number.isSafeInteger()
。
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
第二个被称为最小安全整数 :
Number.MIN_SAFE_INTEGER
的值是最小的整数n,这样n和n-1都可以精确地表示为一个Number值。
Number.MIN_SAFE_INTEGER
的值是-9007199254740991( – (2 53 -1))。
倒数第二个被称为最大安全整数 :
Number.MAX_SAFE_INTEGER
的值是最大的整数n,使得n和n + 1都可以精确地表示为Number值。
Number.MAX_SAFE_INTEGER
的值是9007199254740991(2 53 -1)。
Number.MAX_VALUE
会告诉你在你的JS实现中表示的最大的浮点值。 答案可能是:1.7976931348623157e + 308。 但这并不意味着每个10 ^ 308以下的整数都可以精确地表示出来。 正如你的例子所显示的,除了2 ^ 53之外,只有偶数可以表示出来,而当你走出数字线时,差距会变得更大。
如果你需要大于2 ^ 53的精确整数,你可能需要使用一个bignum包,它允许任意大的整数(在可用内存的范围内)。 我碰巧知道的两个包是:
BigInt由Leemon
和
紧缩