Python中的浮点数到分数转换

Abd*_*eeb 4 python floating-point type-conversion fractions

在Python 3.52中进行从浮点类型到分数类型转换的主题的练习时,我发现了两种不同转换方式之间的区别。

第一种方法是:

>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> print(f)
2709702426188841/2199023255552      #Answer
Run Code Online (Sandbox Code Playgroud)

第二种方法是:

>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(str(x))
>>> print(f)
123223/100                          #Answer
Run Code Online (Sandbox Code Playgroud)

我想知道这两个不同答案背后的原因吗?抱歉,如果这是一个愚蠢的问题,我是编程和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
Run Code Online (Sandbox Code Playgroud)

Mat*_*nen 5

再次是因为浮点数不是存储在以10为基数(十进制),而是存储在以2为基数(二进制)中。

以10为底的有限长度数字可能是以2为底的重复小数。而且由于浮点数是固定大小的,因此重复的小数会被截断,从而导致不准确。

当您使用as_integer_ratio以2为底的重复小数的数字时,由于以10为底的基数到2的转换略有不正确,您会得到一些愚蠢的分数。如果将这两个数字相除,则该值将非常接近原始数字。

例如,虽然以10为底的1/10 = 0.1,并且不是重复的小数,但实际上是以2为底的重复小数。就像以10为底的1/3 = 0.333...。

>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)
Run Code Online (Sandbox Code Playgroud)

如果Python的输出是准确的,则即使0.1在提示符下输入,也将看到1.00000 ... 01之类的内容,从而看到此错误。但是在一般情况下,Python会向您隐藏这种不准确性,从而导致混乱。