结算脚本用 round 保留整数,2.5 得到 2,3.5 得到 4。财务用 Excel 的 ROUND 算出来是 3 和 4,同一批数据两边差 1 分。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,Python 3 的 round 用的是银行家舍入,遇到正好 .5 时取最近的偶数,目的是减少累计偏差。业务上常用的四舍五入是逢五进一,两套规则在 .5 这个点上必然不同。
「银行家舍入」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
from decimal import Decimal, ROUND_HALF_UP
q=lambda x: Decimal(str(x)).quantize(Decimal('1'), rounding=ROUND_HALF_UP)
print(q('2.5'), q('-2.5'))
权限不要一口气开到最大,先加到够用再往上试,范围小才好收。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
具体做法是,先确认业务口径 结算类一般要求四舍五入 别用内置 round;改用 Decimal 加 ROUND_HALF_UP 显式指定;封装一个金额舍入函数 全项目只调它;测试覆盖 0.5 1.5 2.5 和负数四个边界。
最后用这个标准收尾,2.5 输出 3 和 Excel 的 ROUND 一致 对账差额归零。
