什么时候乘法的顺序在python?

时间:2016-02-25 06:17:17

标签: python numpy

我使用动态编程编写了一个程序,我花了很长时间才发现代码的不同版本出了问题。它如下:

#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,所以我不认为是这种情况。还有其他可能性吗?

2 个答案:

答案 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