在Python 3.52中对float类型到Fraction类型转换的主题进行练习时,我发现了两种不同转换方式之间的区别。
第一种方法是:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> print(f)
2709702426188841/2199023255552 #Answer
第二种方法是:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(str(x))
>>> print(f)
123223/100 #Answer
我想知道这两个不同答案背后的原因?很抱歉,如果这是一个愚蠢的问题,我是编程和Python的新手。
编辑:我找到了一种方法,可以通过limit_denominator
方法将第一种方法获得的不准确分数转换为精确分数:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> f = f.limit_denominator(100)
>>> print(f)
123223/100
答案 0 :(得分:4)
然而,这又是因为浮点数不存储在基数10(十进制)中,而是存储在基数2(二进制)中。
基数为10的有限长度的数字可能是base-2中的重复小数。并且因为浮点数是固定大小,重复小数会被截断,导致不准确。
当你使用as_integer_ratio
作为base-2中重复小数的数字时,由于base-10到base-2转换中的轻微不准确,你会得到一些有点愚蠢的分数。如果将这两个数字分开,则该值将非常接近原始数字。
例如,虽然1/10 = 0.1 in base-10并且不是重复小数,但它实际上是base-2中的重复小数。就像1/3 = 0.333 ...在基数10中。
>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)
如果Python的输出是准确的,即使你在提示中输入0.1
,你也会看到这一点,方法是输出1.00000 ... 01作为输出。但是Python 在一般情况下隐藏了</ em>这种不准确性,导致混淆。
答案 1 :(得分:2)
这实际上是一个非常好的问题。不同结果背后的原因是x
不是真正的1232.23
,因为1232.23
没有精确的浮点表示,所以1232.23
的最近浮点表示的小数表示是2709702426188841/2199023255552
,但是当您使用str(1232.23)
时,它会将其视为确切的值1232.23
,并返回该数字的真实最佳小数表示。