在不和谐的服务器上练习代码高尔夫时,我们发现一旦数字变大,我们的代码将停止工作,结果将开始变得混乱。

主要计算是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/

10-12 18:48