numpy.dot在处理大数组时是否存在精度限制?

3

针对大数组,numpy.dot是否会出现错误?我使用的是一台4 GHz Intel Core i7处理器和32 GB 1600 MHz DDR3内存的iMac。我进行了一个简单的实验,比较了使用for循环和向量化计算从1到一个大数的平方和。当总和足够大时,向量化方法是错误的。请参见下面的实验:

i = 3024617
sum([j**2 for j in range(1,i)]) - np.dot(np.arange(1,i,dtype=np.int64), np.arange(1,i, dtype=np.int64))

i = 3024618
sum([j**2 for j in range(1,i)]) - np.dot(np.arange(1,i,dtype=np.int64), np.arange(1,i, dtype=np.int64))

第一个差异 - 对于任何i < 3024617,差异为0

第二个差异 - 对于任何i >= 3024618,差异为一个大整数

我希望对于所有整数i,这个差异都是0。


1
可能会溢出。 - juanpa.arrivillaga
1
np.dotx=np.arange(1,i,dtype=object) 匹配 Python 的 sum。但它比 np.int64 版本慢得多。 - hpaulj
如果我不使用dtype=np.int64,同样的事情也会发生。 - Bryan R
1个回答

1
Python的整数是无界的。 int64 仅限于表示带符号64位整数的范围:
>>> i = 3024617
>>> x = sum([j**2 for j in range(1,i)])
>>> x
9223371388520336796
>>> hex(x)
'0x7fffff690c418d9c'
>>> x.bit_length()
63

所以这个总和可以适应一个有符号的64位整数。再加上i ** 2,它就不能适应了:

>>> x += i**2
>>> hex(x)
'0x800007bb0de78dad'
>>> x.bit_length()
64

在有符号的64位整数中,无法准确表示该总和。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接