11.8. 十进制浮点运算

decimal 模块提供了一种 Decimal 数据类型用于十进制浮点运算。 相比内置的 float 二进制浮点实现,该类特别适用于

  • 财务应用和其他需要精确十进制表示的用途,

  • 控制精度,

  • 控制四舍五入以满足法律或监管要求,

  • 跟踪有效小数位,或

  • 用户期望结果与手工完成的计算相匹配的应用程序。

例如,使用十进制浮点和二进制浮点数计算70美分手机和5%税的总费用,会产生的不同结果。如果结果四舍五入到最接近的分数差异会更大:

  1. >>> from decimal import *
  2. >>> round(Decimal('0.70') * Decimal('1.05'), 2)
  3. Decimal('0.74')
  4. >>> round(.70 * 1.05, 2)
  5. 0.73

Decimal 表示的结果会保留尾部的零,并根据具有两个有效位的被乘数自动推出四个有效位。 Decimal 可以模拟手工运算来避免当二进制浮点数无法精确表示十进制数时会导致的问题。

精确表示特性使得 Decimal 类能够执行对于二进制浮点数来说不适用的模运算和相等性检测:

  1. >>> Decimal('1.00') % Decimal('.10')
  2. Decimal('0.00')
  3. >>> 1.00 % 0.10
  4. 0.09999999999999995
  5. >>> sum([Decimal('0.1')]*10) == Decimal('1.0')
  6. True
  7. >>> sum([0.1]*10) == 1.0
  8. False

decimal 模块提供了运算所需要的足够精度:

  1. >>> getcontext().prec = 36
  2. >>> Decimal(1) / Decimal(7)
  3. Decimal('0.142857142857142857142857142857142857')