核心原因:float 是有限精度的
Python 的 float 类型本质上是 IEEE 754 双精度浮点数,它使用 64 位来存储数值,其中:
-
1 位符号位
-
11 位指数位
-
52 位尾数位(有效数字)
这意味着它只能表示 2^53 个有限精度的数(大约 9 万亿个),而 [0, 1] 区间内的实数是 不可数无穷的(连续统),远远超过了 float 的表示能力。
>>> 0.1 + 0.2 == 0.3
False
>>> format(0.1, '.55f')
'0.1000000000000000055511151231257827021181583404541015625'
0.1 在二进制中是无限循环小数,无法精确表示,只能近似。
二进制小数无法表示 0.1 的根本原因,就是因为它的小数位只能由:
0.5,0.25,0.125,0.0625,0.03125,…
这些 以 5 结尾的十进制小数 相加而成,永远无法精确凑出 0.1。
你想用这些数“拼”出 0.1,但:
于是你只能不断地“逼近”,但 永远无法精确到达。
结果是:
0.1 在二进制中是一个 无限循环小数:
0.110=0.00011001100110011001100110010012
就像十进制中 1/3 = 0.3333... 永远写不完一样。
二进制小数的“颗粒度”只能拼出最后一位是 5 的十进制数,而 0.1 不是这种数,所以永远表示不全。