Точные дроби с Python

Я не вижу математических результатов, которые я ожидаю от следующего кода, который, как я считаю, должен создавать Harmonic Series:

from fractions import Fraction

def sum_fracs(n):
    if n == 1:
        return 1
    return 1/n + sum_fracs(n - 1)

for n in range(1, 6):
    print(sum_fracs(n).as_integer_ratio())
    
for n in range(1, 6):
    print(Fraction(sum_fracs(n)))

Выход:

(1, 1)
(3, 2)
(8256599316845909, 4503599627370496)
(2345624805922133, 1125899906842624)
(1285402393645329, 562949953421312)
1
3/2
8256599316845909/4503599627370496
2345624805922133/1125899906842624
1285402393645329/562949953421312

Ни один из подходов не дает

1   

3/2

11/6    

25/12   

137/60

как я и надеялся. Я знаю, что у чисел с плавающей запятой могут быть ошибки округления, но я надеюсь, что что-то такое базовое будет возможно в Python.

Любая помощь очень ценится.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
32
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы запускаете Fraction(x), где x — поплавок. Слишком поздно, вы уже потеряли точность, поэтому точность вашей дроби такая же, как и у поплавка.

Используйте Fraction в функции:

def sum_fracs(n):
    if n == 1:
        return 1
    return Fraction(1, n) + sum_fracs(n - 1)

for n in range(1, 6):
    print(sum_fracs(n).as_integer_ratio())

выход:

(1, 1)
(3, 2)
(11, 6)
(25, 12)
(137, 60)

NB. это четко указано в документации fraction

Note that due to the usual issues with binary floating-point (see Floating Point Arithmetic: Issues and Limitations), the argument to Fraction(1.1) is not exactly equal to 11/10, and so Fraction(1.1) does not return Fraction(11, 10) as one might expect. (But see the documentation for the limit_denominator() method below.)

Спасибо за это. Я заметил, что это работает и без .as_integer_ratio().

Robin Andrews 18.03.2022 09:11

Другие вопросы по теме