You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中round(0.975,2)与round(0.975*100)/100结果差异原因及规避方法

Python中round()函数的浮点数舍入异常解析

问题复现

测试代码

a=0.975
print(round(a,2))
print(round(a*100)/100)

a=-0.975
print(round(a,2))
print(round(a*100)/100)

a=1.975
print(round(a,2))
print(round(a*100)/100)

a=-1.975
print(round(a,2))
print(round(a*100)/100)

输出结果

0.97
0.98
-0.97
-0.98
1.98
1.98
-1.98
-1.98

原因解析

1. 浮点数的二进制存储误差

十进制小数转二进制浮点数时,大部分数值无法精确表示,只能存储为最接近的近似值:

  • 0.975实际存在内存中的值是略小于0.975的0.9749999999999999778;
  • 1.975的存储值则是略大于1.975的1.9750000000000001776。

这种误差方向的差异是核心原因,而-1到1区间内的数值更容易出现这类问题,是因为该区间的浮点数尾数精度更高,部分十进制小数的近似值会偏向于略小于原值,超出区间的数值则可能偏向略大于原值。

2. round()的"四舍六入五成双"规则

Python的round()采用银行家舍入规则:当舍入位是5时,会把结果舍入到最近的偶数位。

  • 对于存储值略小于0.975的0.9749999999999999778,它离0.97(百分位为7,奇数)更近,所以round(0.975, 2)返回0.97;
  • 当执行0.975*100时,浮点运算的误差积累可能让结果略大于97.5,此时round()会舍入到偶数98,除以100后得到0.98;
  • 而1.975的存储值略大于原值,无论直接舍入到两位小数,还是先乘100舍入再除以100,结果都会偏向1.98,所以两次输出一致。

规避方法

1. 用decimal模块做精确运算

decimal模块支持高精度十进制运算,完全避开浮点数存储误差,还能自定义舍入规则:

from decimal import Decimal, ROUND_HALF_UP

a = Decimal('0.975')
# 四舍五入保留两位小数
print(a.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP))  # 输出0.98
# 先乘100取整再转回两位小数
print((a * Decimal('100')).quantize(Decimal('1')).quantize(Decimal('0.00')))  # 输出0.98

2. 手动添加偏移量修正误差

针对简单场景,可以给数值加一个极小的偏移量,确保舍入方向符合预期:

def round_fix(num, n):
    # 加1e-10避免浮点数误差导致的舍入偏差
    return round(num + 1e-10, n)

a = 0.975
print(round_fix(a, 2))  # 输出0.98
print(round_fix(a*100, 0)/100)  # 输出0.98

3. 用字符串格式化控制舍入

字符串格式化默认采用四舍五入规则,直接输出符合预期的结果:

a = 0.975
print("{:.2f}".format(a))  # 输出0.98
print("{:.2f}".format(round(a*100)/100))  # 输出0.98

内容的提问来源于stack exchange,提问作者dalleaux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:15:35