NumPy 在浮点运算中将较低的精度转换为较高的精度



毫无疑问,在其他(也许是所有(语言中都是这种情况,但我只在Python中进行了测试。我的问题是这样的: 当对两个精度不同的值进行算术运算时,为什么 NumPy 以最高精度返回值的 dtype 结果?

例如

import numpy as np
single = np.array([[1, 2, 3], [4, 5, 6]], np.float32)  
double = np.array([[1, 2, 3], [4, 5, 6]], np.float64)
diff = single-double
print "single data type -", single.dtype  
print "double data type -", double.dtype  
print "diff data type -", diff.dtype

收益 率:

单一数据类型 - 浮点

32
双精度数据类型 - 浮点64 比较数据类型 - 浮点64

根据我对浮点精度的理解,diff表示的额外后半部分是不准确的。在这种情况下,将结果转换为最高精度而不是最低精度的原因是什么?

这称为类型强制,至少在 NumPy 中,它将始终以更高的精度强制转换为类型,因为这样您就不会意外丢失精度,也不会溢出。

例如(关于"溢出"(强制float64它(某种(工作:

>>> np.float64(1e40) - np.float32(1)
1e40

但如果它会胁迫float32你会得到:

>>> np.float64(1e40).astype(np.float32) - np.float32(1)
inf

那是因为最大的float323.4028235e+38

>>> np.finfo(np.float32)
finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32)

其原因是数值计算中的一个原理,称为灾难性抵消。

考虑两个浮点数之间的稍微较小的示例。 3.0000900 - 3.000,如果将其转换为小数点后 4 位,或者在您的情况下将其转换为 4 个字节,则我们的结果值为 0。但是,这些值实际上并不相同!我上面演示的现象称为灾难性取消。由于截断甚至四舍五入,我们基本上正在丢失信息。

为了避免这种情况,这些操作的结果始终被类型转换为更精确的类型,因为丢失的信息很小。

答案主要来自数学和数字类型。

type64 的类型包含 type32 的集合,就像实数类型(浮点数(的类型包含整数的类型一样。

无论何时执行计算,如果将结果集映射到较大的数据容器(整数类型 64 而不是 32(中,则可以保证提供令人满意的结果,但如果在可能较短的容器中映射一组值,则无法保证不会截断结果,这意味着生成无效的结果。

float 和 int 也一直都是这样。在大多数语言中,将浮点数与 int 相乘会产生浮点数,因为浮点数(实数(可以在数学上包含 int,而反之则不然(整数类型不包含实数(。

最新更新