Python round函数简单舍入出现误差,是否为预期行为需用Decimal解决?
关于Python round函数行为的解答
首先可以明确:你观测到的属于Python的预期行为,并非BUG
导致这个结果的原因有两个:
- 二进制浮点数的存储精度限制:并非所有十进制小数都可以被二进制双精度浮点数精确表示。你代码中写的字面量
2.45实际存储的是一个略大于十进制2.45的数值,并不刚好卡在2.4和2.5的正中间,所以round操作会向更大的一侧取数得到2.5。 - Python
round函数默认采用银行家舍入规则(四舍六入五成双):当待舍入的数值恰好落在两个可选值的正中间时,会选择末尾为偶数的那一侧。2.25、3.25可以被双精度浮点数精确表示,刚好落在两个可选值的正中间,因此会选择末尾为偶数的2.2、3.2作为结果。
关于是否需要使用Decimal包的建议
如果你的业务场景对精度要求极高,比如涉及金融计算、需要严格遵循常规十进制四舍五入规则,那么非常推荐使用decimal模块,你可以自定义舍入模式满足需求,示例如下:
from decimal import Decimal, ROUND_HALF_UP # 注意传入字符串形式的数值,避免浮点数精度提前污染数据 print(Decimal('2.25').quantize(Decimal('0.1'), rounding=ROUND_HALF_UP)) # 输出2.3 print(Decimal('3.25').quantize(Decimal('0.1'), rounding=ROUND_HALF_UP)) # 输出3.3 print(Decimal('2.45').quantize(Decimal('0.1'), rounding=ROUND_HALF_UP)) # 输出2.5
如果只是普通数值计算、对少量舍入误差容忍度较高,直接使用原生浮点数即可,只要明确其舍入规则就不会出现意料之外的问题。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

