正数之和导致负数

时间:2017-05-13 18:21:53

标签: python numpy overflow

我正在使用numpy来做有趣的事情"计算邻接矩阵中的三角形"任务。 (Given an nxn Adjacency matrix, how can one compute the number of triangles in the graph (Matlab)?

根据我的矩阵Anumpy.matmul()计算A的多维数据集没有问题,但是对于大矩阵numpy.trace()会返回一个负数。

我使用numpy.diagonal()提取对角线,并使用math.sum()和使用for循环对条目求和 - 两者都返回与numpy.trace()相同的负数。

math.fsum()的尝试最终返回(可以正确)数字4,088,103,618 - 对于python和我的64位操作系统来说看起来很小,特别是因为python文档声称整数值是无限的。

肯定这是一个溢出或未定义的行为问题,但不一致的来源是什么?我已经在以下帖子上执行了测试,以成功验证我的系统架构为64位,因此numpy也应该是64位软件包。 Do I have Numpy 32 bit or 64 bit?

为了可视化求和过程,将打印语句添加到for循环中,输出如下所示,星号标记有趣的行。

.
.
.
adding diag val 2013124 to the running total 2140898426 = 2142911550
adding diag val 2043358 to the running total 2142911550 = 2144954908
adding diag val 2035410 to the running total 2144954908 = 2146990318
adding diag val 2000416 to the running total 2146990318 = -2145976562 *
adding diag val 2062276 to the running total -2145976562 = -2143914286
adding diag val 2092890 to the running total -2143914286 = -2141821396
adding diag val 2092854 to the running total -2141821396 = -2139728542
.
.
.

为什么添加2000416到2146990318会产生溢出?总和只有2148990734 - 这是python的一个非常小的数字!

2 个答案:

答案 0 :(得分:1)

Numpy并没有使用" python类型"而是underlying C types,您必须指定满足您的需求。默认情况下,整数数组将被赋予" int _"从文档中键入:

  

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

因此,为什么你会看到溢出。在构造数组时,您必须指定其他类型,以便它不会溢出。

答案 1 :(得分:0)

当您使用标量添加时,您可能会收到警告:

>>> import numpy as np
>>> np.int32(2146990318) + np.int32(2035410)
RuntimeWarning: overflow encountered in long_scalars
-2145941568

所以是的,它与溢出有关。最大32位整数是2.147.483.647!

要确保您的数组支持更大范围的值,您可以将数组(我假设您对数组进行操作)转换为int64(或浮点值):

array = array.astype('int64')  # makes sure the values are 64 bit integers

或创建数组时:

import numpy as np
array = np.array(something, dtype=np.int64)

NumPy使用固定大小的整数,这些不是任意精度整数。 默认情况下它是32位整数或64位整数,哪一个取决于您的系统。例如,即使为64位编译python + numpy,Windows也使用int32