在不和谐的服务器上练习代码高尔夫时,我们发现一旦数字变大,我们的代码将停止工作,结果将开始变得混乱。
主要计算是a=a*10+!(a%2)
,而我们产生的该系列中第一个会导致意外结果的a是a=1010101010101010
(预期:10101010101010101
与实际: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?,这似乎可以解释为什么结果像它们一样,但是我很好奇控制台表面下会发生什么,这些结果出乎意料。还是对简单定义为JS中未定义的数字进行算术运算的行为?
最佳答案
参见此documentation。
它提到JavaScript Number的值用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);
关于javascript - JS中的加法如何处理大数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48571084/