一尺之槌,日取其半,1075日而竭
今天的故事源自数月前我在 r/learnpython 上回答的一个问题。以下是对该问题的转述:
将 64 位浮点数 1.0 不断除以 2,多少次后恰好变为 0?
x, i = 1.0, 0
while x:
x /= 2.0
i += 1
print(i) # 1075fn main() {
let mut x = 1.0f64;
let mut i = 0;
while x != 0. {
x /= 2.0;
i += 1;
}
println!("{}", i); // 1075
}let x = 1,
i = 0
while (x) {
x /= 2
i++
}
console.log(i) // 1075
古语云:“一尺之槌,日取其半,万世不竭”。但很显然,此话不适用于这个问题。浮点数的精度是有限的,当 x / 2
足够小时,浮点数终无法表示,便会得到结果 0。如以上代码所示,循环将终结在第 1075 次。
1075 次。这表明 64 位浮点能表示的最小数在 $2^{-1075}$ 这个量级,再小的数超出了表示范围,也就归于零了。但 1075 这个数很奇怪,它离 1024 很近,但又多出来一些,有零有整的,这是为什么呢?