实数公式进入计算机以后
数学公式通常在实数域中书写,而计算机只能保存有限多个状态。一个十进制数即使输入时看起来很短,转成二进制后也可能是无限展开;一次乘法或开方的精确结果也常常不在可表示集合中。于是计算过程不是“精确实数运算的较快版本”,而是一串运算后紧跟舍入的离散过程。
误差分析要回答四个不同问题:输入数据本身是否精确,问题对输入扰动是否敏感,所用算法是否放大了本可避免的舍入误差,最终数值离精确答案有多远。把这些问题混成一句“有浮点误差”无法指导计算。可靠的报告应指出误差的尺度、来源和传播路径。
浮点表示与 IEEE 风格舍入模型
规格化浮点数
给定基数 β≥2、有效位数 p 和指数范围,非零规格化浮点数写成
x=±(d0.d1⋯dp−1)ββe,d0=0. 舍入到最近可表示数记为 fl(x)。若中间结果既不溢出也不落入渐进下溢区,则
fl(x)=x(1+δ),∣δ∣≤u, 其中 u 称为单位舍入误差。对“舍入到最近值”的系统,
u=21β1−p。
在二进制 IEEE 风格系统中,有限数还包括带符号零、靠近零的次正规数,并与正负无穷和 NaN 一起规定异常结果。次正规数让绝对间距逐渐缩小,避免在最小规格化数处突然跳到零;但此时统一的相对误差界可能失效。溢出得到无穷或触发环境规定的异常,NaN 会沿后续运算传播。因此,舍入模型的使用前提必须写明“结果处于正常有限范围”。
常见的两个量不应混淆。u 是一次正确舍入的最大相对误差;从 1 到下一个更大的浮点数的距离常记为 εmach。二进制舍入到最近值时,
u=2−p,εmach=21−p=2u.
binary64 有 p=53,故 u=2−53≈1.11×10−16,而 1 的下一浮点邻居与它相差 2−52≈2.22×10−16。某些软件把后一个量也叫 machine epsilon,使用前应先核对定义。
对基本运算 ∘∈{+,−,×,/},在精确结果正常且除数非零时,可写成
fl(x∘y)=(x∘y)(1+δ),∣δ∣≤u.
这是对“每一次已舍入运算”的局部描述,不表示一长串运算只有一次误差。若 n 个小舍入因子相乘且 nu<1,常用
j=1∏n(1+δj)=1+θn,∣θn∣≤γn:=1−nunu
把累计效应压缩成一个界。它说明短计算通常只有 O(nu) 的相对扰动,但也提醒我们:运算次数、数据尺度和相减结构同样重要。
例 1:四位十进制系统中的吸收
设 β=10、p=4,采用舍入到最近值,则 u=5×10−4。按给定次序计算
(10,000+1)−10,000. 第一步的精确结果是 10,001=1.0001×104。四位系统只能保留
1.000×104,所以
fl(10,000+1)=10,000. 该步相对误差为 1/10,001≈9.999×10−5<u,完全符合局部舍入模型。第二步却得到零,而原表达式等于一。小数 1 被大数的间距“吸收”,随后相减使丢失的信息无法恢复。局部误差很小并不保证最终相对误差很小。
消去误差:相减暴露已有误差
两个接近数相减时,前导有效位相互抵消,结果本身很小。减法的最终舍入未必特别大;危险在于两个操作数此前各自携带的绝对误差,在小差值的尺度上会成为巨大的相对误差。这叫消去性相减。它与精确恒等式中的正常约分不同,关键是被减数已经过近似计算。
例 2:等价改写避开平方根相减
在只能保留八位十进制有效数字的环境中,计算
f(x)=1+x−1,x=10−8. 精确的平方根约为 1.000000005,舍入到八位后成为 1.0000000,直接相减给出 0。先作有理化则有
f(x)=1+x+1x. 即使分母按八位舍入为 2.0000000,也得到 5.0000000×10−9。更精细的值为
2.00000000510−8≈4.9999999875×10−9. 两个公式在实数中完全等价,但第二个计算图没有把两个接近的一阶量相减,因此保留了小结果的有效数字。
常见修复方式不是盲目提高精度,而是先改写公式:用有理化替换相近根式之差,用 log1p 型计算替换 log(1+x) 在小 x 处的直接求值,用 expm1 型计算替换 ex−1,或把二次方程的一个根稳定算出后由根的乘积得到另一个根。提高精度能推迟信息丢失,结构改写才消除诱因。
条件数描述问题本身的敏感性
设精确问题为 y=f(x)。绝对条件数衡量输入绝对扰动造成的输出绝对变化;当 x 与 f(x) 非零时,相对条件数衡量相对变化。对可微标量函数,局部条件数为
κabs(x)=∣f′(x)∣,κrel(x)=f(x)xf′(x).
于是小扰动满足一阶近似
∣f(x)∣∣f(x+Δx)−f(x)∣≈κrel(x)∣x∣∣Δx∣.
条件数属于问题和所选输入、输出尺度,不属于某段程序。κ 大表示问题病态:即使算法完全稳定,输入末位的不确定性也可能变成输出前几位的变化。κ 适中而结果仍差,才应重点检查算法和实现。
例 3:靠近极点时输入扰动被放大
考虑 f(x)=1/(1−x)。由
f′(x)=(1−x)21,κrel(x)=1−xx. 在 x=0.99 处,条件数为 99,精确输出是 100。若输入变为
x=0.9901,输入相对改变量为
0.990.0001≈1.0101×10−4, 而 f(x)=1/0.0099≈101.0101,输出相对变化约
1.0101×10−2。放大倍数约为 100,与局部条件数给出的预测一致。这里更换等价程序不能消除极点附近的敏感性;应提高输入精度、远离奇异参数,或诚实报告不确定度。
求和也有数据相关的条件数。若 s=∑ixi=0,对各项独立相对扰动可用
κsum=∣∑ixi∣∑i∣xi∣
衡量敏感性。大量正负项抵消时分母很小,求和问题本身就可能病态;改变求和次序、从小到大累加或补偿求和可以减少算法误差,却不能恢复输入中原本不存在的精度。
前向误差、后向误差与稳定性
前向误差与后向误差
对问题 y=f(x) 和算法输出 y,前向误差是
∥y−f(x)∥, 它直接比较答案。后向误差寻找最小输入扰动 Δx,使
y=f(x+Δx), 并度量 ∥Δx∥。若一个算法对每个允许输入都能把计算结果解释为邻近问题的精确解,且相对后向误差与 u 同阶,就称它后向稳定。
后向稳定不等于前向误差一定小。局部上可概括为
相对前向误差≲κrel(x)×相对后向误差.
因此,“稳定算法 + 良态问题”才导向高相对精度。稳定算法遇到病态问题时可能正确地显示数据不够精确;不稳定算法遇到良态问题时则会浪费本可保留的数字。
例 4:同一结果的前向与后向读法
令 f(x)=x2、x=2,算法返回 y=4.0004。精确值为 4,相对前向误差是
4∣4.0004−4∣=10−4. 把结果视为某个邻近输入的精确平方,取
x=4.0004=21.0001≈2.0000999975. 相对后向误差约为
2∣x−2∣≈4.9999×10−5. 而 f(x)=x2 的相对条件数恒为 2,所以“条件数乘后向误差”约为
9.9998×10−5,正好解释前向误差的量级。三种量各有角色:后向误差评价算法,条件数评价问题,前向误差评价最终答案。
在线性方程、最小二乘或微分方程离散中,残差常是可直接计算的后向信息,但残差不是误差本身。必须结合算子条件数、数据尺度和离散误差,才能把小残差转成“解接近”的结论。
一套可复用的误差检查顺序
面对数值表达式,可依次检查:先写清输入的绝对或相对不确定度;再找奇点、重根、接近抵消和极端尺度以判断条件数;然后画出实际计算顺序,标出每次舍入、下溢与溢出风险;最后用更高精度、等价公式或独立算法复算。只报告许多小数位不是精度证明,最后稳定的位数应由误差界或交叉核验支持。
练习
练习 1:区分单位舍入误差与相邻间距
- 所属知识
- 浮点表示
- 难度
- 2/5
一个十进制浮点系统有 p=5 位有效数字并舍入到最近值。求 u 与 1 的下一较大浮点数到 1 的距离,并给出舍入 x=3.1415926 的结果和相对误差上界。
查看提示
舍入到最近值时,单位舍入误差是 1 附近向上间距的一半。
查看解答
有
u=21101−5=5×10−5,εmach=101−5=10−4. 五位舍入给 fl(x)=3.1416。实际相对误差为
3.1415926∣3.1416−3.1415926∣≈2.36×10−6<u.
练习 2:稳定计算很小的根式差
- 所属知识
- 消去误差
- 难度
- 2/5
把 9+h−3 改写为避免消去的形式,并在 h=10−6 时计算到十位有效数字。
查看提示
乘以共轭式,把小量留在分子。
查看解答
乘以共轭式得到
9+h−3=9+h+3h. 代入 h=10−6,分母约为 6.0000001667,故
9.000001−3≈1.666666620×10−7. 直接计算需要先保存两个约为 3 的数再相减,改写后则直接把小参数按正常尺度传递到结果。
练习 3:幂函数的相对条件数
- 所属知识
- 条件数
- 难度
- 3/5
对 f(x)=xn、x=0,求相对条件数。若 n=20 且输入相对误差不超过 3×10−6,估计输出的一阶相对误差上界。
查看提示
计算 xf'(x)/f(x),并注意 x 非零。
查看解答
因为 f′(x)=nxn−1,所以
κrel(x)=xnxnxn−1=∣n∣. n=20 时,一阶相对误差约不超过
20×3×10−6=6×10−5. 这只描述输入扰动的传播;若计算 x20 的算法另有舍入误差,还应再加入算法误差界。
练习 4:给极限公式选择稳定计算图
- 所属知识
- 稳定性
- 难度
- 3/5
函数 g(x)=(1−cosx)/x2 在小 x 处直接计算容易失去有效数字。给出等价稳定形式,求 x→0 的极限,并说明为什么改写有效。
查看提示
使用半角公式
1−cosx=2sin2(x/2)。
查看解答
由半角公式,
g(x)=x22sin2(x/2)=21(x/2sin(x/2))2. 因此
x→0limg(x)=21. 直接形式先把两个接近 1 的数相减;改写后计算的是接近 1 的比值再平方,没有小差值承载全部有效数字。实际实现还可在极小 x 时用专门的 sinc 近似。
前后联系与资料
课程 · 2012Introduction to Numerical Analysis
Laurent Demanet
用于核对 M10 各类算法的误差阶、稳定性条件、停止准则和可复算例题。
打开官方来源
MIT 18.330 Introduction to Numerical Analysis 提供浮点误差、条件数和数值线性代数的课程脉络,可用于复核本章的舍入模型、稳定性术语与后续算法分析。
有限精度不是计算结束后附加的一条免责声明,而是算法设计的一部分。先区分问题是否病态,再判断算法是否稳定,最后用前向误差说明答案质量,才能知道应当改写公式、提高输入精度,还是接受问题本身无法提供更多可靠数字。