是否可以证明所有双浮点数的 a-b+b = a ?

计算科学 浮点 精确 准确性 数字
2021-12-16 18:57:02

我想知道等式:a-b+b = a 对于 a 是否始终成立,b 属于双精度浮点数和 |a|>=|b|。

如果等式是正确的,我该如何证明呢?

如果不是,什么前提条件可以使等式正确?

一个反例表明等式不正确,所以我现在想知道,不等式 |((ab)+b)-a|<=ulp(a) 是否正确,我如何证明不等式?

我已经测试了下面的 python 代码半小时,不等式 |a-b+ba|<=ulp(a) 似乎成立。

def getulp(x):
x = float(x)
k = frexp(x)[1]-1
if x == 0.0:
    return pow(2, -1074)
if (k<1023)&(k>-1022):
    return pow(2,k-52)
else:
    return pow(2,-1074)



while 1> 0:
k = np.random.randint(-100, 100)
ub = np.float_power(2,k-1)
db = np.float_power(2,k)
j = np.random.randint(-100, 100)
ub2 = np.float_power(2, j - 1)
db2 = np.float_power(2, j)
x = np.random.uniform(ub,db,1)
y = np.random.uniform(ub2,db2,1)
if x>y:
    temp = x-y+y
    if np.fabs(temp-x)>getulp(x):
        print x
        print y
        print "The inequality false"
else:
    temp = y-x+x
    if np.fabs(temp-y)>getulp(y):
        print x
        print y
        print "The inequality false"

感谢@Kirill 的反例,我将解释为什么我需要证明这个等式。我想证明,图像 a,b 是一条线的两个端点,然后如果我知道 b 和 ab 的值,我想证明我可以得到 a 的值而不会出现大于一个 ULP(a) 错误的错误. 所以我可以给出条件 |a|>=|b| 或|a|<=|b|,但我不能限制它们的实际值。

1个回答

您有时可以使用支持浮点运算的Z3等 SMT 求解器来证明此类结果(或获得反例) 。这是你的定理的一个版本的证明,它说|((x+y)y)x|223|x|什么时候x>y>1x+y32在 32 位浮点运算中:

λ> import Data.SBV
λ> :set -XScopedTypeVariables
λ> prove $ \(x::SFloat) (y::SFloat) -> fpIsNormal (x+y) &&& x .> y &&& y .> 1 ==> fpAbs (((x+y)-y)-x) .< fpAbs x * 1.1920928955078125e-7
Q.E.D.

这里我使用了 Haskell 中的 sbv 包。如果它适用于 32 位浮点数,它也应该适用于 64 位浮点数。