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

sun*_*ots 4 python numpy sum python-3.x

100,000,000使用以下方法对第一个正整数求和:

import numpy as np
np.arange(1,100000001).sum()
Run Code Online (Sandbox Code Playgroud)

我返回:987459712,它与公式不匹配:N(N+1)/2for N=100000000。即,公式返回5000000050000000

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

np.arange(1,65536).sum() == ((65535+1) * 65535)/2
Run Code Online (Sandbox Code Playgroud)

然而,这个数字65536似乎是一个关键点,因为

np.arange(1,65537).sum() == ((65536+1) * 65536)/2
Run Code Online (Sandbox Code Playgroud)

返回False

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

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

Dee*_*ace 5

似乎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')
Run Code Online (Sandbox Code Playgroud)

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

>> np.arange(1, 100000001, dtype=np.int64).sum()
500000005000000
Run Code Online (Sandbox Code Playgroud)

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


Jim*_*ard 5

其实并不是numpy很难猜测,只是默认的 int类型与 C long 类型相同:

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

对于 Windows 系统,长整型是 32 位,即使在 64 位版本上也是如此(请参阅此处了解更多信息),因此默认情况下使用的是int32.

正如 DeepSpace 所建议的,设置dtypeint64就可以了。arange这可以在方法中或方法中完成sum


此外,您写道:

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

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

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

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

返回False

这是因为第二个总和超过了 的int32最大值,而第一个总和没有超过:

>> np.arange(1,65536).sum() < np.iinfo(np.int32).max
True    
>>> np.arange(1,65537).sum() < np.iinfo(np.int32).max
False
Run Code Online (Sandbox Code Playgroud)

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


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

  • @MarkDickinson [`sum`](https://docs.scipy.org/doc/numpy-1.13.0/reference/ generated/numpy.sum.html#numpy.sum) 方法使用默认的 int 大小,该大小在 [大多数类 UNIX 系统](https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models) 是 `int64`。显然,根据链接的模型,带有“cygwin”的 Windows 也应该使用“int64”。 (2认同)