在不和谐服务器上练习代码高尔夫时,我们发现一旦数字变大,我们的代码就会停止工作,结果会变得混乱。
主要计算是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?被发布在所述不和谐中,这似乎解释了为什么结果就像他们一样但是我很好奇在控制台表面下发生了什么意外的结果。或者算术运算对JS中大小简单定义为未定义的数字的行为是什么?
答案 0 :(得分:3)
请参阅此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);