首页/开发/软件测试速查/浮点与金额精度处理
用例设计方法62 条

浮点与金额精度处理

浮点数不能精确表示多数十进制小数(0.1 + 0.2 现象);金额与计费场景用最小货币单位或十进制类型,并用舍入用例验证规则。

软件测试速查开发更新于 2026-10-13

浮点与金额精度是什么

浮点数不能精确表示多数十进制小数:0.1 加 0.2 得到 0.30000000000000004。金额与计费场景要用最小货币单位整数或十进制类型(Java BigDecimal、Python Decimal),并用舍入用例验证业务约定;精度问题一旦进入账务,对账与退款成本远高于测试成本。

基本信息

现象0.1 加 0.2 不等于 0.3(二进制浮点表示误差)
处理方式最小货币单位整数、Decimal 与 BigDecimal 等十进制类型
舍入规则四舍五入与银行家舍入结果不同,按业务约定断言
比较方式容差比较(approx、delta),避免等号
高危场景金额、计费、税率、折扣与积分累计

现象与处理

现象与处理
# 现象
0.1 + 0.2   # 0.30000000000000004
# 处理(Python)
from decimal import Decimal
Decimal('0.1') + Decimal('0.2')   # Decimal('0.3')
# 断言(pytest)
from pytest import approx
assert 0.1 + 0.2 == approx(0.3)

典型使用场景

  • 金额计算:订单、退款、优惠分摊的精确结果。
  • 税率与折扣:百分比相乘后的舍入边界。
  • 积分与余额:累计加减中误差不放大。
  • 报表对账:总额与明细逐层分摊后仍对平。
  • 跨语言接口:下游以浮点接收时的精度损失。
  • 落库校验:DECIMAL 字段精度与代码层口径一致。

常见误区与正解

误区后果正解
float 存金额累加出现分币误差整数分或 Decimal
等号比较浮点偶发失败容差比较
期望值同式算法误差双向抵消手算或独立来源
舍入规则想当然与对账系统对不上先确认业务约定
测试舍入:银行家舍入与四舍五入结果不同,需按业务约定断言分位值。
数据库也要对得上:DECIMAL 字段精度与代码层 Decimal 保持同一口径,落库前后各断言一次。
整数分是常见落法:内部用分存储与计算,展示层再格式化成带小数的货币字符串。

断言建议

  • 容差贴合业务精度:金额用分或厘级容差,比例指标可适当放宽。
  • 期望值用独立来源:手算样例、账务系统导出或外部计算器。
  • 多层分摊逐级断言:总额、分摊、明细三段各自校验。

易错点

  • 用浮点相等断言金额结果,出现 0.30000000000000004 类失败
  • 只测整数金额,忽略分币与折扣小数相乘后的舍入边界
  • 期望值用与被测相同的浮点公式算出,误差被同步掩盖
  • 先转 float 再转 Decimal,损失发生在转换这一步
  • 舍入规则未确认就写断言,四舍五入与银行家舍入互相打架
  • 测试数据只用 0.5 这类二进制可精确表示的数值,掩盖真实精度问题
  • 积分类数值长期累加不做定期结算校验,误差缓慢累积无人发现

数据来源与参考

  • IEEE 754(浮点标准)
  • Python decimal 模块文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌