代码之家  ›  专栏  ›  技术社区  ›  trashgod

float.as_integer_ratio()的实现限制

  •  10
  • trashgod  · 技术社区  · 15 年前

    最近,一位记者提到 float.as_integer_ratio() 在python 2.6中是新的,注意到典型的浮点实现本质上是实数的有理近似。出于好奇,我不得不尝试:

    >>> float.as_integer_ratio(math.pi);
    (884279719003555L, 281474976710656L)
    

    我有点惊讶没有看到更多 accurate 因应 Arima ,

    (428224593349304L, 136308121570117L)
    

    例如,此代码:

    #! /usr/bin/env python
    from decimal import *
    getcontext().prec = 36
    print "python: ",Decimal(884279719003555) / Decimal(281474976710656)
    print "Arima:  ",Decimal(428224593349304) / Decimal(136308121570117)
    print "Wiki:    3.14159265358979323846264338327950288"
    

    生成此输出:

    python:  3.14159265358979311599796346854418516
    Arima:   3.14159265358979323846264338327569743
    Wiki:    3.14159265358979323846264338327950288
    

    当然,考虑到64位浮点数字所提供的精度,结果是正确的,但这让我不禁要问:我如何才能更多地了解 as_integer_ratio() ?谢谢你的指导。

    其他链接: Stern-Brocot tree Python source .

    3 回复  |  直到 6 年前
        1
  •  3
  •   mirh AAAfarmclub    6 年前

    使用的算法 as_integer_ratio 只有 considers powers of 2 in the denominator .这是一个(可能的) better algorithm .

        2
  •  3
  •   Alex Martelli    15 年前

    我可以推荐一下吗? gmpy 的实现 Stern-Brocot tree :

    >>> import gmpy
    >>> import math
    >>> gmpy.mpq(math.pi)
    mpq(245850922,78256779)
    >>> x=_
    >>> float(x)
    3.1415926535897931
    >>> 
    

    同样,结果是“在64位浮点的精度范围内是正确的”(53位“所谓的”尾数;-),但是:

    >>> 245850922 + 78256779
    324107701
    >>> 884279719003555 + 281474976710656
    1165754695714211L
    >>> 428224593349304L + 136308121570117
    564532714919421L
    

    …GMPY的精度是如此之高 更便宜的 (就分子和分母值之和而言)比Arima的要少得多,比python 2.6的要少得多!-)

        3
  •  3
  •   fesno    15 年前

    你可以用

    fractions.Fraction.from_float(math.pi).limit_denominator()
    

    分数包含在内,因为可能是3.0版。 然而,math.pi没有足够的精度返回30位的近似值。