【问题标题】:Is there a way to return a fully reduced ratio when calling .as_integer_ratio()?调用 .as_integer_ratio() 时有没有办法返回完全降低的比率?
【发布时间】:2018-11-21 00:37:17
【问题描述】:

在某些浮点数上调用 .as_integer_ratio() 时,我注意到一些奇怪的事情。例如:

(2.2).as_integer_ratio()

这将返回一个元组: (2476979795053773, 1125899906842624)

我想知道我是否可以让它以某种方式直接返回 11/5?

【问题讨论】:

  • 除 11/5 不正确。 2.2 can't be represented exactly(在 IEEE 754 二进制浮点中没有 2.2 这样的东西)。给出的比率是最接近 2.2 的可表示值的完全缩减比率。

标签: python python-3.x floating-point floating-accuracy


【解决方案1】:

Floating point can't actually represent most values as typed。 2.2 是最接近 2.2 的值的便捷简写,但 2.2 实际上并不存在:

>>> print('{:.16f}'.format(2.2))
2.2000000000000002

如果您想要精确的十进制表示,则需要使用 the decimal module 而不是 float

>>> from decimal import Decimal
>>> Decimal('2.2').as_integer_ratio()  # Constructing from str is *mandatory* for proper precision
(11, 5)

【讨论】:

    【解决方案2】:

    @ShadowRanger 的回答是正确的。值“2.2”被转换为最接近的二进制小数。 .as_integer_ratio() 返回那个二进制分数。但是,还有其他附近的有理数在转换为浮点数时会产生相同的二进制表示。使用Stern-Brocot 树可以找到更简单的分数。

    gmpy2 有一个 Stern-Brocot 算法的实现,它公开为 .as_simple_fraction()

    >>> gmpy2.mpfr("2.2").as_integer_ratio()
    (mpz(2476979795053773), mpz(1125899906842624))
    >>> gmpy2.mpfr("2.2").as_simple_fraction()
    mpq(11,5)
    

    【讨论】:

      猜你喜欢
      • 2021-12-10
      • 1970-01-01
      • 2013-04-26
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多