0.1 + 0.2 ≠ 0.3 是因 ieee 754 双精度浮点数用二进制表示十进制小数时必须截断近似,0.1 和 0.2 均为无限循环二进制小数,52 位尾数截断后误差累积;decimal('0.1') + decimal('0.2') == decimal('0.3') 成立,因其以字符串初始化、避开 float 解析,全程精确十进制运算。

Python 中浮点数运算出现精度丢失,不是 Python 的缺陷,而是所有遵循 IEEE 754 双精度标准的语言共有的底层限制。根本原因在于:十进制小数(如 0.1、0.2)在二进制中无法精确表示,只能截断近似。
为什么 0.1 + 0.2 ≠ 0.3?
-
0.1转成二进制是无限循环小数:0.00011001100110011...(周期为 1001) -
0.2同样是无限循环:0.0011001100110011... - Python 的
float只有 52 位尾数(mantissa),必须截断,导致存储值略小于真实十进制值 - 截断后的两个近似值相加,误差累积 → 实际结果是
0.30000000000000004 - 所以
0.1 + 0.2 == 0.3返回False
这个现象在 JavaScript、Java、C 等语言中完全一致,和 Python 无关。
Decimal('0.1') + Decimal('0.2') == Decimal('0.3') 为什么成立?
-
Decimal不走二进制浮点路径,而是用整数 + 小数位数的方式精确表示十进制数 - 关键前提是:必须用字符串初始化,例如
Decimal('0.1') - 若写成
Decimal(0.1),会先让 Python 把0.1解析为已失真的float,再包装——精度早已丢失 - 示例:
from decimal import Decimal print(Decimal('0.1') + Decimal('0.2') == Decimal('0.3')) # True print(Decimal(0.1) + Decimal(0.2) == Decimal(0.3)) # False
round(2.675, 2) 得到 2.67 而非 2.68 怎么回事?
-
2.675在二进制中无法精确表示,实际存储值略小于2.675(比如2.6749999999999998) -
round()对“恰好位于中间”的情况默认采用 银行家舍入(ROUND_HALF_EVEN),但前提仍是输入值本身已失真 - 所以它不是四舍五入逻辑错了,而是输入值从一开始就不等于你写的字面量
- 正确做法:用
Decimal控制输入和舍入:from decimal import Decimal, getcontext, ROUND_HALF_UP getcontext().rounding = ROUND_HALF_UP print(Decimal('2.675').quantize(Decimal('0.01'))) # Decimal('2.68')
真正需要警惕的,不是“怎么修显示”,而是是否在关键路径上混用了 float 和 Decimal(比如 Decimal('1.1') + 2.5),一旦触发隐式转 float,精度就不可逆地丢了。金融、对账、科学计算中,这种混用比精度设置错误更危险。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











