Numpy 在除以一个大整数时转换为 python 浮点数,这是一个错误吗?

Numpy casts to python float when dividing by a large integer, is this a bug?

这是一个最小的代码示例:

import numpy as np

x = np.array(1e-35, dtype=np.double)
y = int(1e19)
print( type(x/y) )

y = int(1e20)
print( type(x/y) )

在我的机器上,前一种情况打印 numpy.float64,后一种情况打印 float。我想具体的数字在不同的机器上会有所不同,但重点是对于小整数,除法保留类型,而对于大整数,类型被转换为 Python 浮点数。我想知道这是否是 Numpy 中的错误,以及除了手动将所有内容转换为 double 之外是否有任何解决方案。

这似乎无害,但是当我尝试编写一个 ufunc 并且强制转换仅发生在数组的某些元素上时,return 类型变为 object,程序抛出“无法强制提供输出参数”错误。

输出类型发生变化,因为 int(1e19) 可以安全地转换为 np.int64,而 int(1e20) 不适合 np.int64,因此无法安全转换(您可以用 y.bit_length() 检查一下)。结果,y 首先保存为纯 Python 对象(可变大小的整数),然后 Python 将其转换为纯 Python 浮点对象,因此结果也是一个 pure-Python float 对象。发生这种情况是因为 Numpy 尝试根据本机类型应用自己的语义规则。当它不能使用它们时(由于 unsafe/impossible 强制转换),回退 pure-Python 基于对象的语义被应用 导致 pure-Python对象。不过,这似乎是 known issue。您可以在 GitHub 查看相关问题并与 Numpy 开发人员讨论以获取更多信息。

我认为最好的策略是不要依赖这种行为。事实上,当一个类浮点值乘以一个大整数时,这个大整数总是首先被转换为一个类浮点值(由于语义规则)。这种转换可能会导致精度损失以及随后的乘法。因此,我认为最好自己转换大整数,以记住整数值可能无法完美表示。