我正在使用NumPy 1.7.1版.
现在我遇到了一个我不明白的奇怪取消:
>>> import numpy as np
>>> a = np.array([ 883, 931, 874], dtype=np.float32)
数学上0.1-a应该是0.1.
现在让我们计算一下
这个表达式以及绝对和相对误差:
>>> a+0.1-a
array([ 0.09997559, 0.09997559, 0.09997559], dtype=float32)
>>> (a+0.1-a)-0.1
array([ -2.44155526e-05, -2.44155526e-05, -2.44155526e-05], dtype=float32)
>>> ((a+0.1-a)-0.1) / 0.1
array([-0.00024416, -0.00024416, -0.00024416], dtype=float32)
第一个问题:这是一个相当高的绝对和相对误差,这仅仅是灾难性的取消,不是吗?
第二个问题:当我使用数组而不是标量时,NumPy能够以更高的精度进行计算,请参见相对误差:
>>> a+np.array((0.1,)*3)-a
array([ 0.1, 0.1, 0.1])
>>> (a+np.array((0.1,)*3)-a)-0.1
array([ 2.27318164e-14, 2.27318164e-14, 2.27318164e-14])
我想这只是0.1的数值表示.
但是,如果使用标量而不是0.1-a中的数组,为什么NumPy无法以相同的方式处理呢?
解决方法:
如果使用双精度,情况将发生变化.对于单精度(np.float32),您期望得到什么:
a = np.array([ 883, 931, 874], dtype=np.float64)
a+0.1-a
# array([ 0.1, 0.1, 0.1])
((a+0.1-a)-0.1) / 0.1
# array([ 2.27318164e-13, 2.27318164e-13, 2.27318164e-13])
在表达式中间使用np.array((0.1,)* 3)会将所有内容都转换为float64,这说明了第二个结果中的较高精度.