Ограничения реализации float.as_integer_ratio () - PullRequest
11 голосов
/ 16 января 2010

Недавно корреспондент упомянул float.as_integer_ratio(), новость в Python 2.6, отметив, что типичные реализации с плавающей запятой - это по существу рациональные приближения действительных чисел.Заинтригованный, я должен был попробовать π:

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

Я был слегка удивлен, не увидев более точный результат из-за Арима ,:

(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 и Источник Python .

Ответы [ 3 ]

5 голосов
/ 16 января 2010

Вы получаете лучшие приближения, используя

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

Дроби включены с версии 3.0. Однако math.pi недостаточно точен, чтобы вернуть 30-значное приближение.

4 голосов
/ 16 января 2010

Алгоритм, используемый as_integer_ratio только , учитывает степени 2 в знаменателе .Вот (вероятно) лучший алгоритм .

3 голосов
/ 16 января 2010

Могу ли я порекомендовать gmpy реализацию дерева Штерн-Броко :

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...