使用给定种类的浮点数(比如float16),构建完全错误的求和是很简单的。例如,使用Python / NumPy:
import numpy as np
one = np.float16(1)
ope = np.nextafter(one,one+one)
np.array((ope,one,-one,-one)).cumsum()
# array([1.001, 2. , 1. , 0. ], dtype=float16)
在这里,我们使用cumsum
来强制执行朴素求和。如果由于其自身原因未被限制,numpy
将使用不同的求和顺序,从而得出更好的答案:
np.array((ope,one,-one,-one)).sum()
# 0.000977
以上是基于取消操作的。为了排除这类示例,让我们只允许非负项。对于朴素求和,仍然可以给出非常错误的总和的例子。以下是每个相等于10^-4的10^4个相同项的总和:
以上是基于取消操作的。为了排除这类示例,让我们只允许非负项。对于朴素求和,仍然可以给出非常错误的总和的例子。以下是每个相等于10^-4的10^4个相同项的总和:
np.full(10**4,10**-4,np.float16).cumsum()
# array([1.0e-04, 2.0e-04, 3.0e-04, ..., 2.5e-01, 2.5e-01, 2.5e-01],
dtype=float16)
最后一项多除以了4。
同样地,允许numpy
使用成对求和会得到更好的结果:
np.full(10**4,10**-4,np.float16).sum()
# 1.0
可以构造出比成对求和更好的求和方式。选择小于1的分辨率eps,我们可以使用1、eps、0、eps、3x0、eps、7x0、eps、15x0等,但这需要使用非常多的项。
我的问题是:使用float16和仅使用非负项,需要多少项才能获得一个比成对求和结果高至少一倍的结果。
附加题: 使用“正数”而不是“非负数”的情况下,相同的问题。这是否可能?