numpy中连续整数的总和不正确

时间:2017-11-10 14:41:57

标签: python python-3.x numpy sum

使用以下内容汇总第一个100,000,000正整数:

import numpy as np
np.arange(1,100000001).sum()

我返回987459712,与N(N+1)/2的公式:N=100000000不符。即,公式返回5000000050000000

发布之前,我写了以下内容,返回True

np.arange(1,65536).sum() == ((65535+1) * 65535)/2

然而,数字65536似乎是一个关键点,如

np.arange(1,65537).sum() == ((65536+1) * 65536)/2

返回False

对于大于65536的整数,代码返回False,而低于此阈值的整数返回True

有人可以解释我在计算总和方面做错了什么,或者代码发生了什么?

2 个答案:

答案 0 :(得分:4)

似乎numpy有时候很难猜测正确的数据类型。

在我的系统上,Win 10 64位,Python 3.4.4,numpy 1.13.1:

>>  np.arange(1, 100000001).sum()
987459712
>>  np.arange(1, 100000001).dtype
dtype('int32')

但是,如果我们“帮助”numpy它会得到正确的结果:

>> np.arange(1, 100000001, dtype=np.int64).sum()
500000005000000

错误的结果显然是由于32位整数溢出造成的。

答案 1 :(得分:4)

numpy难以猜测事情,the default int类型与C long类型相同:

  

int_:默认整数类型(与C long相同;通常为int64或int32)

对于Windows系统,long为32位,即使在64位版本上也是如此(有关详情,请参阅here),以便默认情况下使用int32

正如DeepSpace建议的那样,将dtype设置为int64就可以了。这可以在arangesum方法中完成。

另外,你写道:

  

发布之前,我写了以下内容,返回True

     

np.arange(1,65536).sum() == ((65535+1) * 65535)/2

     

然而,数字65536似乎是一个关键点,如

     

np.arange(1,65537).sum() == ((65536+1) * 65536)/2

     

返回False

这可以解释为第二笔金额超过int32的最大值,而第一笔金额超过{+ p>

>> np.arange(1,65536).sum() < np.iinfo(np.int32).max
True    
>>> np.arange(1,65537).sum() < np.iinfo(np.int32).max
False

当然,由于Python 3的任意精度int,Python计算是正确的。

这就是我们许多人无法复制的原因。在大多数Unix上,64位机器的默认int大小为int64(因为C长为64位)因此这些整数的总和等于预期值。