О классе фракции в py3 - PullRequest
       107

О классе фракции в py3

0 голосов
/ 28 октября 2019

Есть ли способ найти число в позиции kth после десятичной точки в float представлении дроби? k до 10^6. Я попытался преобразовать float(Fraction) в str, это не дало мне желаемой точности.

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Вы могли бы использовать высокоточный пакет с плавающей запятой, такой как decimal, чтобы вычислить это, но если вам нужна только одна цифра, то есть более эффективные методы: мы можем вычислить триллионную цифру(например) 34/23 (например) за долю секунды, используя целые числа, не превышающие 1000 для всего вычисления.

Вот простая функция, которая дает k -ую цифру послеточка дроби p/q:

def digit(p, q, k):
    """
    Return the kth digit after the point (k >= 1)
    of the fraction p / q.  p, q and k should be integers.
    """
    return pow(10, k-1, q) * p % q * 10 // q

И пример: 34/23 имеет десятичное расширение 1.4782608695652173913043478260869565217..., поэтому давайте воспользуемся функцией выше, чтобы получить несколько цифр из этого расширения

>>> digit(34, 23, 1)
4
>>> digit(34, 23, 3)
8
>>> digit(34, 23, 20)
0
>>> digit(34, 23, 30)
6
>>> digit(34, 23, 1_000_000_000)  # billionth digit after the point
5

Вот объяснение того, почему это работает, используя 34/23 в качестве примера: предположим, что мы хотим вычислить 5-е место после десятичной запятой. Вот как мы можем сделать это вручную: сначала мы умножим на 10**4, чтобы переместить места перед требуемой цифрой влево от точки:

10 ** 4 * 34/23 = 14782.608695652173913043478260869565217...

Теперь мы отбрасываем целую часть и оставляем только дробную часть:

дробная часть = 0.608695652173913043478260869565217 ...

Затем мы умножаем на 10, чтобы получить нужную цифру слева от десятичной точки:

10 * дробная часть = 6.08695652173913043478260869565217 ...

И, наконец, мыотбросить дробную часть результата, оставив только 6, то есть нужную нам цифру.

Все эти операции легко выполнить эффективно в вычислительном отношении: дробная часть 10**(k-1) * p / q равна (10**(k-1) * p % q) / qи мы можем эффективно вычислить 10**(k-1)*p % q в Python, используя форму с тремя аргументами pow как pow(10, k-1, q) * p % q. Теперь напишите r для числителя, и мы хотим вычислить целую часть r * 10 / q. Но это всего лишь r * 10 // q, используя оператор целочисленного деления Python.

Таким образом, все становится просто:

pow(10, k-1, q) * p % q * 10 // q
1 голос
/ 28 октября 2019

Вы ищете модуль decimal в Python (поставляется из коробки с Python).

from decimal import *

division = 5 / 3
print(division)  # 1.6666666666666667

getcontext().prec = 6
division = Decimal(5) / Decimal(3)
print(division)  # 1.66667
...