fractions.fraction能真正避免浮点误差,但必须从构造开始杜绝float输入;fraction(0.1)因0.1在二进制中本就是近似值(3602879701896397/36028797018963968),正确写法是fraction('0.1')或fraction(1,10)。

Python 的 fractions.Fraction 能真正避免浮点误差,做加减乘除、比较、化简都保持精确有理数表示——前提是别混进浮点字面量。
为什么直接传 0.1 会出错?
Fraction(0.1) 不等于 1/10,因为 0.1 在二进制浮点中本身就是近似值(实际是 3602879701896397/36028797018963968)。结果会得到一个巨大、无意义的分子分母。
- 正确做法:用字符串初始化,
Fraction('0.1')→Fraction(1, 10) - 或用整数对:
Fraction(1, 10) - 避免:
Fraction(0.1)、Fraction(1/10)(后者先算浮点再转)
Fraction 支持哪些输入格式?
构造函数接受多种安全输入,关键看来源是否可精确表达:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 两个整数:
Fraction(3, 4)→ 3/4 - 单个整数:
Fraction(5)→ 5/1 - 十进制字符串:
Fraction('3.14')→ 314/100 → 自动约分为 157/50 - 分数字符串:
Fraction('1/3')→ 1/3 - 带符号或空格:
Fraction('- 2/7')合法 - 不支持科学计数法字符串,如
'1e-1'会报ValueError
运算后分母爆炸?怎么控制大小?
连续运算(尤其带大分母)会让分子分母迅速变大,影响性能和可读性,但 Fraction 每次运算后自动约分,所以“爆炸”只发生在原本就不可约的大数之间。
- 检查是否已最简:
f.numerator和f.denominator始终互质 - 若需限制分母上限,用
f.limit_denominator(max_denominator=100),它返回最接近的、分母 ≤ 给定值的分数(基于连分数逼近) - 例如:
Fraction('3.1415926').limit_denominator(100)→Fraction(311, 99) - 注意:
limit_denominator()是近似操作,不是化简
和小数、整数混合运算时要注意什么?
只要一端是 Fraction,另一端是 int 或 Fraction,结果仍是 Fraction;但一旦出现 float,整个表达式立刻转为 float,精度丢失不可逆。
- 安全:
Fraction(1, 3) + 2→Fraction(7, 3) - 危险:
Fraction(1, 3) + 0.5→0.8333333333333334(float) - 补救:
Fraction(1, 3) + Fraction('0.5')→Fraction(5, 6) - 比较也同理:
Fraction(1, 3) 会先把前者转成 float 再比,失去意义
最易被忽略的是输入源头——哪怕后续所有运算都用 Fraction,只要第一步用了 float 字面量或 float 变量,误差就已固化。字符串或整数对才是可信起点。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










