JS中的加法如何处理大数
How does addition in JS work with big numbers
在 discord 服务器上练习代码高尔夫时,我们发现一旦数字变大,我们的代码就会停止工作,结果会开始变得混乱。
主要计算是 a=a*10+!(a%2)
,我们生成的系列中第一个会导致意外结果的 a 是 a=1010101010101010
(预期:10101010101010101
vs 实际:10101010101010100
).
在调查时我发现计算 10101010101010100 + 1 = 10101010101010100
.
看到之后,我尝试了 10101010101010100 + 2 = 10101010101010102
这让我很困惑。为什么加 1 会产生相同的值而加 2 不会?
更多示例:
10101010101010100 + 3 = 10101010101010104
10101010101010102 + 1 = 10101010101010104
10101010101010104 + 1 = 10101010101010104
我也尝试将数字放在 Number()
中以防止任何自动转换(毕竟是 JS),但结果是一样的。
在短暂的延迟后 What is JavaScript's highest integer value that a number can go to without losing precision? 被发布到所说的 discord 中,这似乎解释了为什么结果是这样的,但是 我很好奇控制台表面下发生了什么这会产生这些意想不到的结果。或者在JS中简单定义为未定义的对大数字的算术运算行为?
看到这个documentation。
里面提到JavaScript一个数的值是用52位来表示的。随着您的数字越来越接近超过该位数,给定范围内可以表示的数字越来越少。
对于Math.pow(2, 52)
和Math.pow(2, 53)
之间的数字,每个整数都可以表示。即:
Math.pow(2, 52) === Math.pow(2, 52) + 0.5
对于Math.pow(2, 53)
和Math.pow(2, 54)
之间的数字(这是10101010101010100
所在的位置),可以表示第二个整数,然后是第四个整数,依此类推,随着范围力量的增长。
console.log('2^52 === 2^52 + 0.5 :',
Math.pow(2, 52) === Math.pow(2, 52) + 0.5);
console.log('2^53 === 2^53 + 1 :',
Math.pow(2, 53) === Math.pow(2, 53) + 1);
在 discord 服务器上练习代码高尔夫时,我们发现一旦数字变大,我们的代码就会停止工作,结果会开始变得混乱。
主要计算是 a=a*10+!(a%2)
,我们生成的系列中第一个会导致意外结果的 a 是 a=1010101010101010
(预期:10101010101010101
vs 实际:10101010101010100
).
在调查时我发现计算 10101010101010100 + 1 = 10101010101010100
.
看到之后,我尝试了 10101010101010100 + 2 = 10101010101010102
这让我很困惑。为什么加 1 会产生相同的值而加 2 不会?
更多示例:
10101010101010100 + 3 = 10101010101010104
10101010101010102 + 1 = 10101010101010104
10101010101010104 + 1 = 10101010101010104
我也尝试将数字放在 Number()
中以防止任何自动转换(毕竟是 JS),但结果是一样的。
在短暂的延迟后 What is JavaScript's highest integer value that a number can go to without losing precision? 被发布到所说的 discord 中,这似乎解释了为什么结果是这样的,但是 我很好奇控制台表面下发生了什么这会产生这些意想不到的结果。或者在JS中简单定义为未定义的对大数字的算术运算行为?
看到这个documentation。
里面提到JavaScript一个数的值是用52位来表示的。随着您的数字越来越接近超过该位数,给定范围内可以表示的数字越来越少。
对于Math.pow(2, 52)
和Math.pow(2, 53)
之间的数字,每个整数都可以表示。即:
Math.pow(2, 52) === Math.pow(2, 52) + 0.5
对于Math.pow(2, 53)
和Math.pow(2, 54)
之间的数字(这是10101010101010100
所在的位置),可以表示第二个整数,然后是第四个整数,依此类推,随着范围力量的增长。
console.log('2^52 === 2^52 + 0.5 :',
Math.pow(2, 52) === Math.pow(2, 52) + 0.5);
console.log('2^53 === 2^53 + 1 :',
Math.pow(2, 53) === Math.pow(2, 53) + 1);