Python 3.6.3连续除法结果异常,请求原因解析
为什么连续除法和单次除法结果不同?
这本质上是双精度浮点数的精度限制导致的问题,Python里的float类型是64位双精度浮点数,它的尾数只有53位有效二进制位——这意味着只有当整数能被表示成m * 2^e(其中m是小于2^53的整数)时,才能被精确存储为float。对于像10**32这种超大整数,本身已经超出了这个精确范围,转换成float时就已经是近似值了。
咱们拆解来看两种计算路径:
连续除法的误差累积
当你执行a/1000/1000时:
- 第一步
a/1000:先把a(10**32)转换成float,然后除以1000(同样转成float)。结果10**29无法被float精确表示,所以存储的是一个非常接近10**29的近似值——这个近似值和真实值的差异很小,但已经存在了。 - 第二步再除以1000:这个微小的误差被进一步放大,最终得到的结果就是
9.999999999999999e+25,和精确的1e+26产生了可见的偏差。
单次除法的“显示巧合”
而a/1000000是直接计算10**32 / 10**6 = 10**26。虽然10**26本身也没法被float精确存储,但由于计算路径更直接,这个结果的float近似值和1e+26的差异小到在打印时被四舍五入成了1e+26——看起来像是精确值,但本质上它还是个近似值,你可以用format(a/1000000, '.20f')查看更精确的数值,会发现它和真实的1e+26其实有微小差异。
如何解决精确计算需求?
如果需要完全精确的结果,有两个可靠方案:
- 用整数除法:
print(a // 1000 // 1000),整数运算不会有精度损失,结果会精确到10**26。 - 使用
decimal模块:这个模块支持高精度的十进制运算,可以完全避免浮点数精度问题,示例代码如下:
from decimal import Decimal a = Decimal('10')**32 print(a / 1000 / 1000) # 输出1E+26,完全精确
内容的提问来源于stack exchange,提问作者B31aim
相关产品推荐
相关产品推荐

