Python fractions模块Fraction(1.2)与Fraction('1.2')结果差异问题
Fraction类浮点数入参与字符串入参返回结果不一致的原因
核心差异来自64位双精度浮点数的二进制存储精度限制,两种入参走的是完全独立的解析逻辑:
- 传入浮点数
1.2时,Fraction会直接读取该值在内存中存储的精确二进制值转换为分数,不会做任何近似拟合处理。
十进制小数1.2转换为二进制是无限循环值:1.001100110011...(0011段无限循环),而Python的float类型遵循IEEE754双精度标准,最多只能存储53位二进制有效位,必须对无限循环部分做截断存储,最终存入内存的根本不是数学意义上精确的1.2,只是一个和1.2差值小于1e-16的近似值。你看到的Fraction(5404319552844595, 4503599627370496)就是这个近似值对应的精确分数表示。日常计算时觉得这个分数等于1.2,只是因为常规计算精度不足以显示出二者之间极小的差值。 - 传入字符串
'1.2'时,Fraction直接按十进制字面量做精确解析,将字符串识别为12/10后做约分处理,自然得到最简分数Fraction(6, 5),全程不经过二进制浮点数转换,不存在精度损耗。
可以通过以下代码验证两个结果的实际差值:
from fractions import Fraction print(Fraction(1.2) - Fraction('1.2')) # 输出结果为 1/45035996273704960
如果需要从浮点数得到符合日常认知的最简分数,可以调用limit_denominator()方法做有理逼近,执行Fraction(1.2).limit_denominator()即可返回Fraction(6, 5)。
内容的提问来源于stack exchange,提问作者apostofes
相关产品推荐
相关产品推荐

