numpy sum没有给出float32类型的正确答案

时间:2014-02-28 23:44:15

标签: python numpy

我使用numpy对数组进行求和,并且它不适用于float32类型。我究竟做错了什么?一旦我直接做了总和,然后我使用numpy.sum。请参阅以下代码

import struct
import numpy as np
import matplotlib.pyplot as plt
import math
from pylab import *
xpt=128
ypt=128
zpt=256
bx1=np.zeros((xpt,ypt,zpt),dtype=float32)
bx2=np.zeros((xpt,ypt,zpt),dtype=float32)
bx3=np.zeros((xpt,ypt,zpt),dtype=float32)

bx1=bx1+1.0
bx2=bx2+1.5
bx3=bx3+2.0

dummy=0.0
for kxi in range (0,xpt) :
  for kyi in range (0,ypt) :
    for kzi in range (0,zpt) :
      dummy=dummy+(bx1[kxi,kyi,kzi]*bx1[kxi,kyi,kzi]+bx2[kxi,kyi,kzi]*bx2[kxi,kyi,kzi]+bx3[kxi,kyi,kzi]*bx3[kxi,kyi,kzi])
print(dummy)

print(np.sum(bx1**2+bx2**2+bx3**2))

两个输出都应匹配。这给出了输出:
30408704.0
3.1323e + 07

直接求和给出了正确的结果,而np.sum给出了错误的结果。但是,如果我使用float64,那么np.sum会给出正确的结果。这背后的原因是什么?

感谢。

3 个答案:

答案 0 :(得分:4)

float32的精度有问题,数字很大。我没有完成如何存储2.25,但是最小的例子

x = 2.25 * np.ones((128, 128, 256), dtype = float32)
y = 2.25 * np.ones((128, 128, 256), dtype = float64)
x.sum() # 8854642.0
y.sum() # 9437184.0
2.25 * 128 * 128 * 256 # 9437184.0

显示您失去了准确性,但使用float64(python的standard float)获得了准确性。

答案 1 :(得分:2)

添加大量小数字时可能导致舍入错误\精度损失的原因。

如果先对一个轴求和,然后对其结果求和。你得到了正确的答案。

print(np.sum(bx1**2+bx2**2+bx3**2, axis=0).sum())

浮点数是一种狡猾的生物,从不相信它们。

答案 2 :(得分:1)

其他回复是这个问题的优秀具体答案。可以在文章What Every Computer Scientist Should Know About Floating-Point Arithmetic中找到对此类问题的一般回答。原版在1991年首次出版时非常棒,在线编辑的转载至少同样出色。