Python如何使用decimal模块实现符合现实场景的标准四舍五入
问题原因
Python 内置 round 函数和 decimal 模块默认采用*银行家舍入(ROUND_HALF_EVEN)规则:当舍入位恰好为5时,会向最近的偶数方向舍入,因此会出现round(2.5)=2、Decimal('3.225').quantize(TWOPLACES)=3.22的结果。你需要的是金融、工程领域通用的ROUND_HALF_UP(四舍五入)*规则:舍入位≥5时进1,<5时舍去,只需在使用decimal模块时指定舍入模式即可。
解决方案
1. 依赖导入
首先导入所需的对象和常量:
from decimal import Decimal, getcontext, ROUND_HALF_UP
2. 两种使用方式
方式1:全局设置舍入模式(推荐,一次配置全局生效)
# 全局指定所有decimal运算默认使用四舍五入规则 getcontext().rounding = ROUND_HALF_UP # 定义保留位数 TWOPLACES = Decimal('0.01') INTEGER = Decimal('1') # 测试案例 print(Decimal('3.225').quantize(TWOPLACES)) # 输出 3.23,符合预期 print(Decimal('3.235').quantize(TWOPLACES)) # 输出 3.24,符合预期 print(Decimal('2.5').quantize(INTEGER)) # 输出 3,和Octave/Matlab结果一致 print(Decimal('3.5').quantize(INTEGER)) # 输出 4,符合预期
方式2:单次运算指定模式(不修改全局配置)
如果不想影响其他decimal运算,可在调用quantize时单独指定舍入模式:
TWOPLACES = Decimal('0.01') res = Decimal('3.225').quantize(TWOPLACES, rounding=ROUND_HALF_UP) # 结果为3.23
3. 后续计算说明
quantize返回的是Decimal对象,本身支持所有算术运算,精度不会丢失,可直接用于后续计算。如果需要转换为普通数值/字符串,可直接调用对应方法:
# 转float float_val = float(res) # 转字符串 str_val = str(res)
注意事项
不要直接将float类型的数值传入Decimal构造函数(如Decimal(3.225)),float本身存在精度损失,会导致传入的数值在构造前就已经出现偏差,建议一律传入字符串形式的数值(如Decimal('3.225'))。
内容的提问来源于stack exchange,提问作者amwink
相关产品推荐
相关产品推荐

