Oracle® Solaris Studio 12.4:数值计算指南

退出打印视图

更新时间: 2015 年 1 月
 
 

2.3.5 有关渐进下溢与突然下溢的两个示例

以下是两个有名的数学示例。第一个示例是计算内积的代码。

sum = 0; 
for (i = 0; i < n; i++) {
 sum = sum + a[i] * y[i]; 
} 
return sum;

利用渐进下溢,结果的精确度为舍入的精确度。在突然下溢中,可能会在几乎所有数字中传递看上去合理实则错误的微小非零和。然而,公平来讲,我们必须承认,为了避免出现这些问题,聪明的编程人员在预见到会出现微小值影响精确度时,会扩大其计算范围。

第二个示例源于复数商,不适用于缩放:

image:a + i · b = (p + i · q)/(r + i · s) 假定 |r / s|≤1

image:=[ (p · (r / s) + q) + i(q · (r / s) - p) ] / [ s + r · (r / s) ]

可以显示出,虽然进行了舍入,但得出的复数结果与准确结果之间的差不大于以下条件下得出的结果与准确结果之间的差:p + i · qr + i · s 每个值的误差都不大于几个 ulp。除了当 ab 都出现下溢外,这种误差分析是面向下溢的,误差是通过以下值的几个 ulp 来界定的:|a + i · b|。将下溢刷新为零时,就不会得出这样的结论。

这种计算复数商的算法非常强大,并且适用于渐进下溢时的误差分析。要在突然下溢的情况下找到同样强大、易于分析且有效的计算复数商的算法是不可能的。在突然下溢的情况下,考虑低级、复杂细节的麻烦从浮点环境的实现工具转移到了用户那里。

利用渐进下溢成功解决但利用突然下溢却失败的问题类要比支持使用突然下溢的人想像的多。许多常用的数值技术都无法成功解决此类问题:

  • 线性方程求解

  • 多项式方程求解

  • 数值积分

  • 收敛性加速

  • 复数除法