你有2个功能;
f(x)= x(((x+1)^(1/2))-(x^(1/2)))
g(x)= x/(((x+1)^(1/2))+(x^(1/2)))
哪一个更准确?
旁注:如果你能解释为什么,这对我有帮助,我感觉它是f(x)因为没有分母,但我并不是100%肯定。
答案 0 :(得分:5)
浮点算法与实际数学完全不同。特别是,浮点运算不是关联的或分布式的。因此,当使用有限精度浮点运算进行求值时,数学上等效的表达式不一定是等价的。即使根据IEEE-754 floating-point standard的要求,加法,减法,乘法,除法和平方根等单个运算产生正确的舍入结果,情况也是如此。
在这种情况下,g()
平均值比f()
更准确,而且x = 500
的具体情况也更准确。原因是f()
遭受减法取消。这在两个浮点数的有效减法期间发生,这两个浮点数的幅度几乎相同。在减法期间取消前导数字,只留下几个进入后续计算的剩余数字。此外,可以通过后续计算放大在被减去的原始操作数的尾随数字中累积的任何舍入误差。可以在this Wikipedia article中找到带有示例的扩展说明。
在这种情况下,sqrt(x+1)
和sqrt(x)
的幅度几乎相同,特别是x
的幅度增加。使用x = 500
的示例并采用IEEE-754单精度算法,我们发现:
x = 500 f(x) = 0x1.659ae0p+3 (11.175156) reference = 0x1.659798p+3 (11.174755)
x = 500 g(x) = 0x1.659798p+3 (11.174755) reference = 0x1.659798p+3 (11.174755)
f(500)
中的错误为420 ulps,而g(500)
提供正确舍入的单精度结果。