【问题标题】:Float to Fraction conversion in PythonPython中的浮点数到分数的转换
【发布时间】:2016-07-03 16:58:55
【问题描述】:

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

第一种方法是:

>>> 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

【问题讨论】:

    标签: python floating-point type-conversion fractions


    【解决方案1】:

    这又是因为浮点数不是以 base-10(十进制)存储,而是以 base-2(二进制)存储。

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

    当您将as_integer_ratio 用于以 2 为底数的重复小数时,由于在以 10 为底数到以 2 为底数的转换中存在轻微的不准确,您会得到一个有点傻的分数。如果您将这两个数字相除,则该值将非常接近您的原始数字。

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

    >>> (0.1).as_integer_ratio()
    (3602879701896397, 36028797018963968)
    

    如果 Python 的输出是准确的,即使您在提示符中输入 0.1,您也会看到这一点,输出类似于 1.00000...01。但是 Python 在一般情况下隐藏这种不准确性,从而导致混淆。

    【讨论】:

    • 似乎是一个更准确的答案。这可能是造成这种异常的原因吗? >>> 0.1+0.1+0.1-0.3 5.551115123125783e-17
    • @AbdulHaseeb:这不是真正的原因,原因正如我所解释的那样,在 base-10 中可以不重复小数表示的数字与在 base-2 中可以表示的数字不同。
    【解决方案2】:

    这实际上是一个很好的问题。不同结果背后的原因是x 不是真正的1232.23,因为1232.23 没有精确的浮点表示,所以1232.23 的最接近浮点表示的小数表示是2709702426188841/2199023255552,但是当你使用 str(1232.23) 它将其视为精确值 1232.23 并返回数字的真正最佳小数表示。

    【讨论】:

      猜你喜欢
      • 2016-06-14
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多