Python 3 десятичных модуля расчета обратимости - PullRequest
0 голосов
/ 29 апреля 2020

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

>>> from decimal import *
>>> a = Decimal('1')
>>> b = Decimal('0.82')
>>> a = a*b/b
>>> print(a)
1

Однако, когда эта операция повторяется, то есть «умножить 100 раз, а затем разделить 100 раз», результат снова не будет точно равен a.

>>> for _ in range(100):
...     a = a*b
...
>>> for _ in range(100):
...     a = a/b
...
>>> a
Decimal('0.9999999999999999999999999965')

Я что-то не так делаю? Можно ли сделать эти вычисления обратимо, чтобы я получил первоначальный результат?

Ответы [ 3 ]

2 голосов
/ 29 апреля 2020

Вместо этого вы можете использовать модуль дробей:

>>> from fractions import Fraction
>>> a = Fraction(1)
>>> b = Fraction(82, 100)
>>> for _ in range(100):
...     a *= b
... 
>>> a
Fraction(189839102486063226543090986563273122284619337618944664609359292215966165735102377674211649585188827411673346619890309129617784863285653302296666895356073140724001, 78886090522101180541172856528278622967320643510902300477027893066406250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
>>> for _ in range(100):
...     a /= b
... 
>>> a
Fraction(1, 1)
2 голосов
/ 29 апреля 2020

Десятичное число не имеет бесконечной точности. Вы можете увеличить его точность , если найдете его слишком неточным.

from decimal import *
getcontext().prec = some larger number
1 голос
/ 29 апреля 2020

Вы также можете воспользоваться реализацией Python бесконечно больших целых чисел, сделав вместо этого нужные целые числа десятичных чисел, умножив их все на достаточно большой коэффициент, и впоследствии разделите результат на тот же коэффициент:

a = 100 # 1 times a factor of 100
b = 82 # 0.82 times a factor of 100
for _ in range(100):
    a = a*b
for _ in range(100):
    a = a//b
print(a)

Это выводит:

100 # divide this by a factor of 100 to get back 1
...