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

javascript如何处理大整数(超过52位)?,javascript,node.js,integer,Javascript,Node.js,Integer,考虑此代码(节点v5.0.0) 为什么a==b为真 javascript可以处理的最大整数值是多少 我正在实现高达2^64的随机整数生成器。有什么陷阱我应该注意吗?回答第二个问题,下面是JavaScript中的最大安全整数: console.log( Number.MAX_SAFE_INTEGER ); 其余的都写在: MAX_SAFE_INTEGER常量的值为9007199254740991。这个 这个数字背后的原因是JavaScript使用了双精度 IEEE 754中规定的浮点格式编号,只

考虑此代码(节点v5.0.0)

为什么
a==b
为真

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


我正在实现高达2^64的随机整数生成器。有什么陷阱我应该注意吗?

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

console.log( Number.MAX_SAFE_INTEGER );
其余的都写在:

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

在此上下文中,Safe指的是表示整数的能力 准确和正确地比较它们。例如
Number.MAX\u SAFE\u INTEGER+1==Number.MAX\u SAFE\u INTEGER+2
将 计算为
true
,这在数学上是不正确的。看见 了解更多信息

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\u SAFE\u INTEGER
的值是这样的最小整数n 那是n和n− 1都可以精确地表示为数值

Number.MIN\u SAFE\u INTEGER
的值为−9007199254740991 (−(253−1) )

最后一个称为:

Number.MAX\u SAFE\u INTEGER的值
是n这样的最大整数 n和n+1都可以精确地表示为一个数值

Number.MAX_SAFE_INTEGER
的值为9007199254740991 (253−1)

.::JavaScript仅支持53位整数::。 JavaScript中的所有数字都是浮点,这意味着整数始终表示为

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

但是,如果乘以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)的情况不可预测。实际的表示有点复杂,但是这个解释应该可以帮助您理解基本问题

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


是全文。

Number.MAX\u VALUE
将告诉您JS实现中可表示的最大浮点值。答案可能是:1.7976931348623157e+308。但这并不意味着每个10^308以内的整数都可以精确表示。正如您的示例代码所示,在2^53之外,只能表示偶数,并且当您在数字行上走得更远时,间距会变得更大

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


为了补充这里的其他答案,值得一提的是它的存在。这允许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 >999999999999999999999999999999999999 N+1 N 10000000000000000000000n >2n**53n 9007199254740992n >2n**53n+1n 9007199254740993n >2n**53n==2n**53n+1n 假的 >1n型 “bigint” >3*4n TypeError:无法混合BigInt和其他类型,请使用显式转换 >BigInt(3)*4n 12n >3*编号(4n) 12 >编号(2n**53n)=编号(2n**53n+1n) 真的
对不起,已经修好了。a和b是相同的数字,相同的数字是相同的或相等的。为什么需要这么大的整数?你能做两个32字符的数字并把它们合并成一个字符串吗?我做了一个以10为基数的浮点数的简单模拟(注意:你的计算机使用的是2为基数!):正如你所看到的,如果你把尾数向上移动,你可以得到像
123456789100000
这样的大数字,但你实际上不能将这个数字增加1;您可以创建的最接近的较高数字是
1234567892000000
> 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