在python中,乘法的顺序何时重要?

在python中,乘法的顺序何时重要?,python,numpy,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

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

#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,所以我认为情况并非如此。还有其他可能性吗?

对于浮点值,通过改变乘法的顺序,您可能会看到细微的差异,尽管我通常认为差异非常小(相对于值的大小),除非中间结果溢出或下溢,但我希望这些情况更加明显

下面是一个简单的例子:

>>> 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
,但由于浮点舍入,情况并非如此。不同平台的实际结果可能不同,但这是我在计算机上得到的结果,它说明了浮点运算的困难之一。

对于浮点值,通过改变乘法顺序,您可能会看到细微的差异,虽然我通常认为差异非常小(相对于值的大小),除非中间结果溢出或下溢,但我预计这些情况会更明显

下面是一个简单的例子:

>>> 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
,但由于浮点舍入,情况并非如此。不同平台的实际结果可能不同,但这是我在计算机上得到的结果,它说明了浮点运算的困难之一。

这里不能发生溢出,因为您使用的是介于0和1之间的数字。 但是,您有浮点错误。看

在运行Python的典型机器上,Python浮点值有53位精度,因此当您输入十进制数0.1时,内部存储的值是二进制分数

下面是一个简单的示例,用两个介于0和1之间的数字来说明:

>>> a = 0.141421356237309515
>>> b = 0.519787654313216655
>>> a*a*b - a*b*a
1.734723475976807e-18

如果这是一个你想做的问题,你可以使用定点算法。请看一看:

这里不能发生溢出,因为您使用的是介于0和1之间的数字。 但是,您有浮点错误。看

在运行Python的典型机器上,Python浮点值有53位精度,因此当您输入十进制数0.1时,内部存储的值是二进制分数

下面是一个简单的示例,用两个介于0和1之间的数字来说明:

>>> a = 0.141421356237309515
>>> b = 0.519787654313216655
>>> a*a*b - a*b*a
1.734723475976807e-18

如果这是一个你想做的问题,你可以使用定点算法。看一看:

你可以比较两个乘积并打印出有问题的条目,以了解它们何时不同。乘法是可交换的,我能看到你得到不同值的唯一方法是,如果你有很长的浮点数,它们也可能“下溢”为零。@BrenBarn是的,但是顺序并不重要,因为所有的乘法器都是概率,所以它们都小于1。你可以比较两个乘积并打印有问题的条目,以了解它们何时不同。乘法是可交换的,我能看到你得到不同值的唯一方法是,如果你有很长的浮点数,它们也可以“底流”为零。@BrenBarn是的,但顺序并不重要,因为所有乘数都是概率,所以它们都小于1。