所以我写了一个简单的脚本来演示几何系列的收敛。
from decimal import *
import math
initial = int(input("a1? "))
r = Decimal(input("r? "))
runtime = int(input("iterations? "))
sum_value=0
for i in range(runtime):
sum_value+=Decimal(initial * math.pow(r,i))
print(sum_value)
当我使用以下值时:
a1 = 1
r = .2
iterations = 100000
我认为收敛为1.250000000000000021179302083
当我更换线路时:
sum_value+=Decimal(initial * math.pow(r,i))
使用:
sum_value+=Decimal(initial * r ** i)
我得到了更准确的值,1.250000000000000000000000002
这到底有什么区别?根据我的理解,它与math.pow
是浮点运算有关,但我只是认为**
是数学幂函数的语法糖。如果它们确实不同,那么在将以下内容输入IDLE时,为什么精度值为200:
>>> Decimal(.8**500)
Decimal('3.50746621104350087215129555150772856244326043764431058846880005304485310211166734705824986213804838358790165633656170035364028902957755917668691836297512054443359375E-49')
>>> Decimal(math.pow(.8,500))
Decimal('3.50746621104350087215129555150772856244326043764431058846880005304485310211166734705824986213804838358790165633656170035364028902957755917668691836297512054443359375E-49')
他们似乎完全一样。这里发生了什么?
答案 0 :(得分:1)
正如您所暗示的那样,差异在于math.pow()
将输入转换为float
,如the documentation中所述:"与内置**运算符不同,数学.pow()将其参数转换为float类型。"
因此,math.pow()
也会提供float
作为答案,与输入是Decimal
(或int
)还是其他任何内容无关。当使用不完全可以表示为float
的数字(但是Decimal
)时,您可能会使用**
运算符获得更精确的答案。
这解释了为什么你的循环在使用**
的情况下会提供更精确的结果,因为你正在使用Decimal
数字提升到一个整数。在第二种情况下,您无意中将float
用于两个计算,然后在已执行操作时将结果转换为Decimal
。如果您使用明确的Decimal
值,则会看到差异:
>>> Decimal('.8')**500
Decimal('3.507466211043403874762758796E-49')
>>> Decimal(math.pow(Decimal('.8'), 500))
Decimal('3.50746621104350087215129555150772856244326043764431058846880005304485310211166734705824986213804838358790165633656170035364028902957755917668691836297512054443359375E-49')
因此,在第二种情况下,Decimal
值会自动转换为float
,结果与上面的示例相同。但是,在第一种情况下,计算在Decimal
域中执行,结果略有不同。