20 分钟
Python 进阶

浮点数精度陷阱

0.1 + 0.2 ≠ 0.3 的原因和解决方案

  • 理解二进制浮点数表示的局限
  • 掌握浮点数比较的正确方法
  • 了解 decimal 精确十进制
  • 知道何时用整数替代浮点数

浮点数精度陷阱

0.1 + 0.2 ≠ 0.3 在几乎所有编程语言中都成立。这不是 Python 的 bug,是 IEEE 754 浮点数标准的本质问题。

问题重现

示例代码(可运行)
ℹ️IEEE 754 双精度

Python 的 float 是 IEEE 754 双精度浮点数,用 64 位存储:1 位符号 + 11 位指数 + 52 位尾数。能精确表示的十进制小数很少,只有 0.5、0.25、0.125 这类 2 的负幂次可以精确表示。0.1 存储为最接近的二进制近似值,所以有微小误差。

正确比较浮点数

示例代码(可运行)

decimal:精确十进制

示例代码(可运行)
⚠️金钱计算铁律

涉及金钱的计算永远不要用 float!浮点误差累积后会导致账目对不上。用 Decimal(精确十进制)或用整数存储最小单位(分)。例如 19.99 元存为 1999 分,所有计算用整数,显示时再除以 100。这是金融系统的标准做法。

用整数避免浮点问题

示例代码(可运行)
二进制原理

0.1 的二进制表示

0.1 在二进制中是无限循环小数:

示例代码(可运行)
选择题

0.1 + 0.2 == 0.3 的结果是?

选择题

金融计算应该用什么类型?

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

内层函数(或 lambda)捕获的是外层变量本身,而不是定义那一刻的值;循环里定义的多个函数,循环结束后调用往往都拿到最后的值。解决办法是用默认参数 f(x=x) 立即绑定,或用工厂函数包一层。配合 LEGB 作用域顺序(局部→外层→全局→内建)理解,90% 的作用域谜题都能解开。

挑战任务

精确价格计算

简单+50 XP

用 Decimal 计算三件商品的总价,含8%税,结果精确到分。

精确价格计算
2 个测试用例

课后作业

浮点数安全比较

中等+20 XP

写一个函数 safe_equal(a, b),用 math.isclose 安全比较两个浮点数。

浮点数安全比较
1 个测试用例