我使用动态编程编写了一个程序,我花了很长时间才发现代码的不同版本出了问题。它如下:
#the old version
if probs[i][k]*probs[k+1][j]*prob > tmp_prob:
tmp_prob = prob*probs[i][k]*probs[k+1][j]
#the new version
res = probs[i][k]*probs[k+1][j]*prob
if res > tmp_prob:
tmp_prob = res
我认为结果应该是相同的,但事实上,它们不是。并且
if probs[i][k]*probs[k+1][j]*prob > tmp_prob:
tmp_prob = probs[i][k]*probs[k+1][j]*prob
,结果与新版本相同。所以我知道问题是probs[i][k]*probs[k+1][j]*prob
并不总是等于prob*probs[i][k]*probs[k+1][j]
。
但他们何时不平等?我认为可能存在溢出,即inf
发生时。但由于probs[i][k]
,probs[k+1][j]
,prob
都是概率所以它们都小于1,所以我不认为是这种情况。还有其他可能性吗?
答案 0 :(得分:2)
对于浮点值,您可能会通过更改乘法的顺序看到轻微的差异,尽管我通常期望差异非常小(相对于值的大小),除非中间结果溢出或下溢,但我希望这些案件更加明显。
这是一个简单的例子:
>>> import math
>>> t = math.sqrt(3.0)
>>> 3*t*t
9.0
>>> t*t*3
8.999999999999998
>>> 3*t*t - t*t*3
1.7763568394002505e-15
>>>
在数学上,两个产品都应该是9.0
,它们的差别应该是0.0
,但由于浮点数的舍入,情况并非如此。实际结果可能因平台而异,但这是我在计算机上得到的结果,它说明了浮点运算的一个难点。
答案 1 :(得分:2)
此处不会发生溢出,因为您使用0到1之间的数字。 但是,您有浮点错误。见https://docs.python.org/2/tutorial/floatingpoint.html
在运行Python的典型机器上,Python浮点数有53位可用精度,因此输入十进制数0.1时内部存储的值是二进制分数
这是一个简单的例子来说明两个数字介于0和1之间:
>>> a = 0.141421356237309515
>>> b = 0.519787654313216655
>>> a*a*b - a*b*a
1.734723475976807e-18
如果这是您想要做的事情的问题,您可以使用定点算术。看看:https://docs.python.org/2/library/decimal.html