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 开发人员讨论以获取更多信息。
我认为最好的策略是不要依赖这种行为。事实上,当一个类浮点值乘以一个大整数时,这个大整数总是首先被转换为一个类浮点值(由于语义规则)。这种转换可能会导致精度损失以及随后的乘法。因此,我认为最好自己转换大整数,以记住整数值可能无法完美表示。
这是一个最小的代码示例:
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 开发人员讨论以获取更多信息。
我认为最好的策略是不要依赖这种行为。事实上,当一个类浮点值乘以一个大整数时,这个大整数总是首先被转换为一个类浮点值(由于语义规则)。这种转换可能会导致精度损失以及随后的乘法。因此,我认为最好自己转换大整数,以记住整数值可能无法完美表示。