使用 ECLiPSe Prolog,lib(ic)
我偶然发现了David H. Bailey 提出的以下问题,“解决科学计算中的数值异常”。Unum book提到了我。实际上,这只是其中的一部分。首先,让我根据 来制定方程(is)/2
。另外,请注意,所有这些十进制数字都以基数 2 浮点数(包括 IEEE)精确表示:
ECLiPSe Constraint Logic Programming System [kernel]
...
Version 6.2development #21 (x86_64_linux), Wed May 27 20:58 2015
[eclipse 1]: lib(ic).
...
Yes (0.36s cpu)
[eclipse 2]: X= -1, Y = 2, Null is 0.80143857*X+1.65707065*Y-2.51270273.
X = -1
Y = 2
Null = 0.0
Yes (0.00s cpu)
所以这确实是0.0(根本没有四舍五入)。但现在与$=
代替is
:
[eclipse 3]: X= -1, Y = 2, Null $= 0.80143857*X+1.65707065*Y-2.51270273.
X = -1
Y = 2
Null = 2.2204460492503131e-16__2.2204460492503131e-16
Yes (0.00s cpu)
此区间不包含 0.0。我知道区间算术通常有点过于近似,如下所示:
[eclipse 4]: 1 $= sqrt(1).
Delayed goals:
0 $= -1.1102230246251565e-16__2.2204460492503131e-16
Yes (0.00s cpu)
但至少等式成立!但是,在第一种情况下,不再包括零。显然我没有理解一些东西。我也尝试过eval/1
,但无济于事。
[eclipse 5]: X= -1, Y = 2, Null $= eval(0.80143857*X+1.65707065*Y-2.51270273).
X = -1
Y = 2
Null = 2.2204460492503131e-16__2.2204460492503131e-16
Yes (0.00s cpu)
Null
不包括的原因是什么0.0
?
(在@jschimpf 出人意料的回答之后编辑)
这是书中第 187 页的引文,我将其解释为数字被精确表示(现在划线)。
使用可以模拟 IEEE单精度的 {3,5} 环境。输入值是完全可表示的。...
{-1, 2}
...完成了
这项工作,用不到...
否则,第 184 页的声明成立:
...
0.80143857 x + 1.65707065 y = 2.51270273
这些方程式当然看起来很无辜。假设精确的十进制输入,该
系统由x = -1 和y = 2 精确求解。
这是用 SICStus 重新检查的library(clpq)
:
| ?- {X= -1,Y=2,
A = 80143857/100000000,
B = 165707065/100000000,
C = 251270273/100000000,
Null = A*X+B*Y-C}.
X = -1,
Y = 2,
A = 80143857/100000000,
B = 33141413/20000000,
C = 251270273/100000000,
Null = 0 ?
yes
所以 -1, 2 是确切的解决方案。
精确的配方
这是一个在输入系数中没有舍入问题的重新表述,但解决方案仍然只是 -∞...+∞。因此,微不足道的正确,但不可用。
[eclipse 2]: A = 25510582, B = 52746197, U = 79981812,
C = 80143857, D = 165707065, V = 251270273,
A*X+B*Y$=U,C*X+D*Y$=V.
A = 25510582
B = 52746197
U = 79981812
C = 80143857
D = 165707065
V = 251270273
X = X{-1.0Inf .. 1.0Inf}
Y = Y{-1.0Inf .. 1.0Inf}
Delayed goals:
52746197 * Y{-1.0Inf .. 1.0Inf} + 25510582 * X{-1.0Inf .. 1.0Inf} $= 79981812
80143857 * X{-1.0Inf .. 1.0Inf} + 165707065 * Y{-1.0Inf .. 1.0Inf} $= 251270273
Yes (0.00s cpu)