Как получить указанное количество десятичных десятичных мест любой фракции?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как получить указанное количество десятичных десятичных мест любой фракции?

Сообщение Anonymous »

Так что я могу сгенерировать много Tuple s, как это:

Код: Выделить всё

(601550405185810455248373798733610900689885946410558295383908863020551447581889414152035914344864580636662293641050147614154610394724089543305418716041082523503171641011728703744273399267895810412812627682686305964507416778143771218949050158028407021152173879713433156038667304976240165476457605035649956901133077856035193743615197184,
191479441008508487760634222418439911957601682008868450843945373670464368694409556412664937174591858285324642229867265839916055393493144203677491629737464170928066273172154431360491037381070068776978301192672069310596051608957593418323738306558817176090035871566224143565145070495468977426925354101694409791889484040439128875732421875)
Все они представляют собой Tuple s двух int s, они представляют фракции с (почти) бесконечной точностью (ограничены только компьютерной памятью), первое число - числитель, второй знаменатель.
Если мы разделяем их, мы получим первые 101 -тоэтальные места π:
, мы разделим их, мы получим первые 101 -таблицы.

Код: Выделить всё

'3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798'
< /code>
Я сделал все, используя целочисленную математику и без использования библиотек. Я не использовал никакой плавающей запятой, потому что я знаю, что они имеют конечную точность, в отличие от бесконечной точности int 
в Python. /> Я написал две правильные функции, чтобы получить n указанные десятичные знаки от любой фракции: < /p>

Код: Выделить всё

from typing import Dict, List, Tuple

def decimalize(dividend: int, divisor: int, places: int) -> str:
div, mod = divmod(dividend, divisor)
result = [f"{div}."]
while mod and places:
div, mod = divmod(mod * 10, divisor)
result.append(str(div))
places -= 1

integral, first, *others = result
return integral + first + "".join(others).rstrip("0")

def pad_cycles(mod: int, places: int, pairs: Dict[int, str], result: List[str]) -> None:
if mod and places:
i = list(pairs).index(mod)
cycle = "".join(list(pairs.values())[i:])
div, mod = divmod(places, len(cycle))
result.append(cycle * div + cycle[:mod])

def decimalize1(dividend: int, divisor: int, places: int) -> str:
div, mod = divmod(dividend, divisor)
result = [f"{div}."]
pairs = {}
while mod and places and mod not in pairs:
div, mod1 = divmod(mod * 10, divisor)
pairs[mod] = (div := str(div))
result.append(div)
mod = mod1
places -= 1

pad_cycles(mod, places, pairs, result)
integral, first, *others = result
return integral + first + "".join(others).rstrip("0")
Они работают, но оба неэффективны, так как они буквально делают длинное разделение. /> Если последние несколько цифр обрезания десятичного расширения составляют 0, и в этом случае результат не должен содержать каких -либо следственных нулей, если только самая первая десятичная цифра не является 0.
Кроме того, вторая функция выходит из цикла, как только она имеет все цифры одного цикла, и строит оставшиеся цифры, повторяя цикл, хотя в каждой итерации выполняется больше работы, в результате он выполняется быстрее, если цикл короткий, и медленнее, если цикл длится дольше. В худшем случае, если цикл длиннее, чем длина , поэтому он выполняет всю дополнительную работу, не завернувшись рано:
In [364]: %timeit decimalize(1, 3, 100)
25.8 μs ± 371 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [365]: %timeit decimalize1(1, 3, 100)
2.07 μs ± 20.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [366]: %timeit decimalize(1, 137, 100)
26.8 μs ± 209 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [367]: %timeit decimalize1(1, 137, 100)
4.94 μs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [368]: %timeit decimalize1(1, 1337, 100)
43.4 μs ± 280 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [369]: %timeit decimalize(1, 1337, 100)
28.6 μs ± 389 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [370]: %timeit decimalize1(1, 123456789, 100)
42.4 μs ± 309 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [371]: %timeit decimalize(1, 123456789, 100)
29.7 μs ± 494 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [372]: a = 60155040518581045524837379873361090068988594641055829538390886302055144758188941415203591434486458063666229364105014761415461039472408954330541871604108252350317164101172870374427339926789581041
...: 2812627682686305964507416778143771218949050158028407021152173879713433156038667304976240165476457605035649956901133077856035193743615197184

In [373]: b = 19147944100850848776063422241843991195760168200886845084394537367046436869440955641266493717459185828532464222986726583991605539349314420367749162973746417092806627317215443136049103738107006877
...: 6978301192672069310596051608957593418323738306558817176090035871566224143565145070495468977426925354101694409791889484040439128875732421875

In [374]: decimalize(a, b, 101)
Out[374]: '3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798'

In [375]: decimalize1(a, b, 101) == decimalize(a, b, 101)
Out[375]: True

In [376]: %timeit decimalize1(a, b, 101)
96.3 μs ± 295 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [377]: %timeit decimalize(a, b, 101)
64.4 μs ± 402 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
< /code>
Как мы можем сделать лучше, чем длинное разделение, чтобы время выполнения резко сокращалось, при этом достигая того же результата (используя целочисленную математику, чтобы получить бесконечную точность фракций)? Предпочтительно это должно быть сделано без использования каких -либо библиотек, как я хотел бы знать алгоритм.

Подробнее здесь: https://stackoverflow.com/questions/795 ... y-fraction
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»