float.as_integer_ratio()的实现限制

时间:2010-01-16 05:19:10

标签: python math

最近,一位记者提到了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 treePython source

3 个答案:

答案 0 :(得分:4)

使用

可以获得更好的近似值
fractions.Fraction.from_float(math.pi).limit_denominator()

从版本3.0开始包含分数。 但是,math.pi没有足够的精度来返回30位数的近似值。

答案 1 :(得分:3)

as_integer_ratio仅使用considers powers of 2 in the denominator使用的算法。这是(可能)better algorithm

答案 2 :(得分:3)

我建议gmpy实施Stern-Brocot tree

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

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

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

... gmpy的精确度比Arima的便宜(以分子和分母值的总和计算)得多,更不用说Python 2.6了! - )