Python 3位小数模计算可逆性

Python 3 decimal module calculation reversability

我正在尝试实现一个可逆物理引擎,所以我决定使用 decimal 模块。所以这显然有效。

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

但是,当重复这个操作时,即"multiply 100 times and then divide 100 times",结果并不完全等于a

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

我是不是做错了什么?是否可以逆向进行这些计算,以便得到初始结果?

小数没有无限精度。如果您觉得它太不准确,您可以increase its precision

from decimal import *
getcontext().prec = some larger number

您可以改用分数模块:

>>> 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)

您还可以利用 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