确保计算完成 64 位(或至少警告溢出)



我正在使用python和NumPy。我有以下基本数量要计算:

(QL * (7**k))**2

哪里

QL = 200003
k = 4

令我困惑的是,它返回了一个错误的(负数(数字,这没有意义。然后我在互联网上查看后意识到问题是因为k是一个 32 位 numpy 整数。

一个最小的工作示例如下:

QL = 200000
k = np.arange(10)[4]
print((QL * 7**k)**2)

这将返回406556672而不是正确答案230592040000000000。这里的数字不是负数,但仍然会出现同样的问题。

我的问题是:

如何确保代码中使用的所有数字都具有尽可能大的整数大小?

我不想为我创建的每个数字明确指定它。

当这样的事情发生时,我怎么能至少强迫 python 警告我?

当你用Python编写QL = 200003; k = 4时,数字被解释为ints。默认情况下,如果要将它们转换为 numpy 数组或标量,则最终会得到系统上默认整数类型的任何内容。

下面是一个使用单元素数组的示例:

QL = np.array([200003])
k = np.array([4])

在我的系统上,我发现两个数组的dtype都是int32。您可以通过选择首选的 dtype 来更改它:

QL = np.array([200003], dtype=np.int64)
k = np.array([4], dtype=np.int64)

如果您在创建时无法访问数组,则始终可以转换它们:

QL = QL.astype(np.int64)
k = k.astype(int64)

对于整数数学来说,一个值得考虑的选项是完全跳过numpy并使用Python的无限精度整数。如果其中一个数字是 numpy 标量或单元素数组,则可以使用item方法检索相应的 Python 对象:

QL = QL.item()
k = k.item()

Numpy 应该至少发出溢出警告,但显然这对于某些操作失败了:https://github.com/numpy/numpy/issues/8987

TL;博士

在您的情况下,kint32类型的 numpy 标量。您可以执行以下任一操作:

对于 numpy 64 位结果:

k = np.int64(k)

对于无限精度的 Python 结果:

k = k.item()

如果不想显式强制转换每个k,可以使用正确的类型创建范围:

k = np.arange(10, dtype=np.int64)[4]

没有可靠的方法可以在不显式指定的情况下为所有新数组设置默认整数类型。

最新更新