Numpy数组浮点精度不具有确定性



因此,当运行下面的狙击时

import numpy as np
X = np.array([-0.20000008], dtype=np.float32)
np.floor((X + 1) / 0.04)
array([20.], dtype=float32)

输出显然是错误的,因为结果应该低于20,并且应该降到19

我知道这是精度误差,但运行以下所有样本会产生正确的结果,尽管它应该具有类似的精度

X = np.array([-0.20000008], dtype=np.float32).item()
np.floor((X + 1) / 0.04) # 19.0
X = np.float32(-0.20000008)
np.floor((X + 1) / 0.04) # 19.0
X = np.array([-0.20000008], dtype=np.float32)
np.floor(X / 0.04 + 1 / 0.04) # array([19.], dtype=float32)
np.floor(np.multiply((X + 1), 1/0.04)) # array([19.], dtype=float32)

如果我将其转换为float64,它也可以工作,但对于我的应用程序来说,它是非常昂贵的转换。坚持使用float32时有什么解决方案吗?

让我们先来理解下面三个例子中的前两个:

在第一个示例中,

np.array([-0.20000008], dtype=np.float32).item()

将生成一个64位的原生pythonfloat(),因此这里没有额外奖励。

在第二个例子中,您创建了一个numpy 32位标量(shape==(), type==np.float32(,它将或多或少地像其他标量一样被处理:因此,一旦添加int(1(,结果将是一个64位数字。

现在有趣的例子实际上是您的第一段代码和第三个例子:在这两种情况下,您现在都有一个数组(shape==(1,), type=np.ndarray(。在使用数组和标量进行操作的情况下,将保留数组的类型。所以现在我们实际上只是有一个问题,分配定律不适用于浮点数。这里的计算依赖于浮点数的最低有效位。

最新更新