Вы могли бы использовать высокоточный пакет с плавающей запятой, такой как 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