☰
数值分析第三版习题解析:浮点误差、收敛阶与选主元
2026/11/2 2:55:33 网站建设 项目流程

简介:这份PDF为Timothy Sauer《Numerical Analysis》第三版(Pearson,2018)的官方教师解答手册,面向使用该教材学习数值方法的高年级本科生、研究生与授课教师,可用来核对课后习题、梳理算法推导与误差分析思路。答案按教材小节逐条对应:从多项式求值、二进制与浮点表示、有效数字损失,到二分法、不动点迭代、牛顿法等求根方法;从高斯消元、LU与PA=LU分解,到Chebyshev插值、三次样条、Bézier曲线与最小二乘;再到Newton-Cotes与高斯求积、Runge-Kutta与刚性方程、打靶法与有限差分等模块,便于按知识点检索对照。压缩包内仅1个PDF文件,体积6.75MB,轻便易存,适合打印或在平板上批注。目前已有3384人学习下载,可作为课程作业与考前复习的参考。

1. 数值分析这门课,考的从来不是「算对」

搜「数值分析 答案 第三版」的人,多半正在被同一类题折磨:手算到第三页,最后一位和标准答案差一个量级。这份配套第三版教材的解答手册,把每一章 Exercises 与 Computer Problems 的推导、命令和输出数值都摊开了,可它最值钱的地方不在最后那个数字,而在数字之前的两三行——为什么这里必须换公式,为什么那里要多除一次。

这场考试有几条相当稳定的规律:误差与浮点表示必出一道计算,解方程必出一道收敛性分析,插值或数值积分必出一道误差项,常微分方程必出一道方法阶数与稳定性。分值也集中,计算题占大头,证明题翻来覆去只考那几个结论。拿分的关键不是算得快,是每一步都能说出依据。适合正在啃这本教材、准备期末或复试笔试的人,也适合每次都在最后一步翻车、需要有人把过程拆开给你看的人。

2. 基础与浮点:嵌套乘法、二进制与有效数字丢失

2.1 嵌套乘法:运算量题到底数乘法还是数加法

多项式求值几乎每份卷子第一页都有。题目给一个多项式和一点,让你用嵌套乘法算值,再数用了多少次乘法和加法。很多人栽在第二问:把朴素算法的 n(n+1)/2 次乘法和嵌套的 n 次乘法搞混,或者忘了把构造 (x−rᵢ) 的减法算进去。

教材里那道典型题:P(x) = 1 + x(1 + x(5 + x(1 + x(6)))),求 P(1/3)。从最内层往外算:6×1/3 = 2,加 1 得 3;3×1/3 = 1,加 5 得 6;6×1/3 = 2,加 1 得 3;3×1/3 = 1,加 1 得 2。四层,四次乘法、四次加法。这个「从内往外」的顺序就是 Horner 规则。

结论直接背:n 次多项式用嵌套乘法需要 n 次乘法、n 次加法;逐项算幂再乘系数,乘法次数是 n(n+1)/2 量级。如果写成带基点的形式 P(x) = c₁ + (x−r₁)(c₂ + (x−r₂)(c₃ + …)),运算量是 n 次乘法、2n 次加法——教材把构造 (x−rᵢ) 的 n 次减法也算进加法一侧了,答题时写清楚这句,就不会被判漏项。

用代码核对一遍,比手算更不容易错:

def horner(coeffs, x): """coeffs 按降幂排列,返回 P(x) 与乘法次数""" result = coeffs[0] mults = 0 for c in coeffs[1:]: result = result * x + c # 每层一次乘、一次加 mults += 1 return result, mults print(horner([6, 1, 5, 1, 1], 1/3)) # (2.0, 4)

coeffs必须降幂传入,[6,1,5,1,1]对应 6x⁴ + x³ + 5x² + x + 1,和上面那个嵌套式展开完全一致。返回值第二个是乘法计数,正好等于len(coeffs) - 1。考试时手算版本要把每层的结果写出来,只写最终答案容易被扣过程分。

提示:题目问「运算量」时,先确认它数的是乘法还是乘加总数。教材的惯例是乘法单独数,加减法合并数,两种写法结果差一倍,别自作主张换算。

2.2 二进制与浮点:舍入到最近规则的三步判定

十进制转二进制分两半:整数部分除 2 取余、倒序读;小数部分乘 2 取整、正序读。会循环的小数要标出来,比如 1/3 = 0.0101…(01 循环),5/7 是三位一循环,0.1 在二进制里根本写不完。这一步写错,后面浮点题全废。

双精度浮点的结构要默写得出:1 位符号、11 位偏置指数(偏置 1023)、52 位尾数,规格化后隐含首位 1,所以有效位是 53 位。机器精度 ε = 2⁻⁵² ≈ 2.22×10⁻¹⁶,这个数在后面的有效数字丢失、精度极限、最优步长里反复出现。

舍入到最近规则分三步判定,这是浮点题的核心考点:

  1. 把数写成 ±1.b₁b₂…b₅₂ × 2ᵉ 的规格化形式,找出第 53 位;
  2. 第 53 位是 0,直接舍;是 1 且其后还有非零位,向前进 1;
  3. 第 53 位是 1 而其后全 0(正好平局),向偶数舍,即让第 52 位保持为 0。

拿 0.9 试一遍:二进制是 1.1100110011…×2⁻¹,第 53 位落在循环的「1」上,后面还有非零位,于是进位,尾数末四位从 …1100 变成 …1101。9.6 的二进制循环节是 0011,第 53 位刚好是 0,直接舍,末四位仍是 …0011。两个数看起来都在循环,结果一个进一个舍,差别只在那一位上,这类题只能老老实实展开。

反直觉的在后面。计算 1 + (2⁻⁵¹ + 2⁻⁵³) 再减 1,答案不是 0,也不是两个小量之和,而是 2⁻⁵¹。因为 2⁻⁵¹ 落在尾数第 52 位,2⁻⁵³ 落在第 54 位,第 53 位恰好是 0,舍完只剩 2⁻⁵¹。换成 1 + (2⁻⁵¹ + 2⁻⁵² + 2⁻⁵³),第 52、53、54 位全为 1,第 53 位为 1 且后面非零,进位一路捅到第 51 位,结果变成 1 + 2⁻⁵⁰,减 1 得 2⁻⁵⁰——多加了 2⁻⁵² 这一个量,最终答案翻了一倍。这是浮点题里最标准的「陷阱」,答题时要写清进位链条,只写结论拿不到过程分。

2.3 有效数字丢失:哪些公式必须重写才能拿分

有效数字丢失的判断标准只有一句:两个几乎相等的数相减,结果的相对误差被放大。考试给一个公式,让你说明它在什么情况下失效、怎么改写,这就是送分题,但每年都有人只写「会产生误差」四个字。

教材开篇那个例子值得记住:(x⁵¹−1)/(x−1) 在 x = 1.00001 处,直接按公式算和用嵌套乘法算,结果差到 4.76×10⁻¹²。原因是 x⁵¹ − 1 相对 x − 1 大得多,分子上一个舍入位就能把商推到第 12 位。这类题的标准答法是:指出抵消发生在哪一步,给出等价变形,再说明变形后每一步都在同量级上运算。

更常考的是二次方程求根。解 x² + 10⁸x + 1 = 0,按公式算小根时 −b + √(b²−4ac) 里 √(b²−4ac) ≈ 10⁸,与 −b 几乎抵消,有效位全丢;改用韦达定理 x₁x₂ = c/a 反推小根,精度立刻回来。

import math a, b, c = 1.0, 1e8, 1.0 disc = math.sqrt(b*b - 4*a*c) x1 = (-b - disc) / (2*a) # 大根,同号相加,无抵消 x2_bad = (-b + disc) / (2*a) # 小根,灾难性抵消 x2_good = c / (a * x1) # 韦达定理反推,稳定

x2_bad的理论值约 −1e−8,实际算出来的有效位大概只剩两三位,x2_good能保住全部 16 位。参数上要注意,这个技巧只在 |4ac| ≪ b² 时必要;如果两根量级接近,原公式反而没问题,别不加判断就一律改写。

还有一类是 √(x+1) − √x 这种差式,改写成 1/(√(x+1) + √x);以及 (1−cos x)/x² 在 x 很小时改写成用半角公式。改写题的评分点通常有三处:指出抵消来源、写出等价式、说明计算量没爆炸。

2.4 基础题演练:三道标准题的答题过程

第一题:把 79 转成二进制。79÷2 = 39 余 1,39÷2 = 19 余 1,19÷2 = 9 余 1,9÷2 = 4 余 1,4÷2 = 2 余 0,2÷2 = 1 余 0,1÷2 = 0 余 1,倒序读得 1001111。答题时把每一步的商和余数排成竖列,最后标一句「余数倒序」,这是标准写法。只写答案的卷子,遇上严一点的阅卷就是半分。

第二题:求 fl(9.6)。先转二进制得 1001.100110011…,规格化成 1.001100110011…×2³,偏置指数 3 + 1023 = 1026。第 53 位是 0,直接舍,尾数保留 0011 循环形状。答题要写三行:二进制展开、规格化形式、舍入判定依据。漏掉「第 53 位为 0」这句,等于没答舍入规则。

第三题:说明 fl(1 + (2⁻⁵¹ + 2⁻⁵³)) − 1 = 2⁻⁵¹。这题分四步:写出 1 的尾数全 0 形式;标出 2⁻⁵¹ 占第 52 位、2⁻⁵³ 占第 54 位;指出第 53 位为 0 故舍;做减法得 2⁻⁵¹。评分点在第 2 步和第 3 步,很多人直接跳到结论。补一句「若再加 2⁻⁵² 则发生进位,结果翻倍为 2⁻⁵⁰」,能额外拿到理解分。

3. 解方程与线性方程组:收敛阶、选主元与迭代矩阵

3.1 三种求根方法的收敛速度对比表

求根这一章的题,一半是算,一半是让你比较。比较题给不出表就别硬写,先把这张表背下来:

方法收敛条件收敛阶每步新的函数计算最容易失分的地方
二分法f 连续、端点异号线性,误差每步减半1 次 f迭代次数写成 k ≥ (b−a)/tol,忘了取 log₂
不动点迭代邻域内 |g′| ≤ L < 1线性,常数 |g′(r)|1 次 g只验证导数小于 1,不说明区间
牛顿法f′ 连续、f′(r) ≠ 0二次1 次 f + 1 次 f′初值随手取,重根情况没讨论
割线法两个初值足够近超线性,约 1.6181 次 f把阶数写成 2

二分法的迭代次数要给公式:k ≥ log₂((b−a)/tol),这是唯一一个能提前算准步数的方法,所以题目问「至少迭代多少次」,一定是在考这一行。不动点迭代的收敛常数就是 |g′(r)|,收敛速度慢在导数接近 1 的时候,这一点在证明题里常被追问。

牛顿法的二次收敛有前提:单根。遇到重根,f′(r) = 0,二次收敛直接退化成线性,误差比值趋近 1 − 1/m(m 是重数)。教材里的标准补救是改成 x − m·f(x)/f′(x),如果重数未知,就用 x − f f′/((f′)² − f f″)。这两种修正答出来一个就够,但要写上「重数 m」的定义。

def newton(f, df, x0, tol=1e-12, maxit=50): x = x0 for k in range(maxit): fx, dfx = f(x), df(x) if dfx == 0: raise ZeroDivisionError("导数为零,牛顿法失效") # 对应 f'(r)=0 的重根情形 step = fx / dfx x_new = x - step if abs(step) < tol * max(1.0, abs(x_new)): # 相对 + 绝对双判据 return x_new, k + 1 x = x_new return x, maxit

step是牛顿修正量,用它的绝对值做停止判据比用 |f(x)| 更可靠,因为 f 的量级随问题变化。tol * max(1.0, abs(x_new))是相对判据,防止根很大时绝对判据过严、根接近 0 时又过松。maxit必须有,否则遇到发散或病态导数会死循环。dfx == 0这个检查在考试里对应「说明牛顿法失效的情形」,写代码时别省。

3.2 精度极限:牛顿法为什么会「停住不动」

有一道题年年出现:给定 f 和足够好的初值,牛顿法迭代到某一步后修正量不再下降,误差稳定在 10⁻⁸ 附近,问原因。标准答案是机器精度限制了可达到的根精度。

推导思路要能写出来:计算 f(x) 时产生的相对误差约 ε,绝对误差约 ε|f(x)|;根附近的误差 δx 与函数误差的关系是 δx ≈ ε|f|/|f′(r)|。x 越接近 r,|f| 越小,这个下界也跟着降,但当 |f| 降到与舍入误差同量级时就降不动了,于是误差卡在 ε|f|/|f′| 上。

重根的情况更糟。f′(r) = 0 时上面那个比值失效,改用展开式分析,能证明误差下界是 √ε 量级,大约是 10⁻⁸。这就是为什么「重根只能算到 8 位」这句话在卷子上值分——它不是玄学,是泰勒展开的直接结果。

答题时建议这么写:先写出 f(x̃) 的舍入误差模型,再用一阶泰勒展开把函数误差换成根误差,最后分单根、重根两种情况给下界。三步齐全,这道题基本满分。

3.3 高斯消元与 PA=LU:运算量和选主元的评分点

高斯消元的运算量是 (2/3)n³ + O(n²),LU 分解同量级,但一次分解之后每次回代只要 O(n²)。题目问「解多个右端项该选哪种做法」,答案就是 LU:分解一次,之后每个右端项只花 O(n²)。只答「LU 更快」不给分,必须写出两个量级。

选主元的理由要说得具体:某一步的主元绝对值很小,用它做除数会把上一步的舍入误差放大 1/|主元| 倍。部分主元策略是每列选绝对值最大的元素换到对角位置,代价是 O(n²) 次比较,相对于 n³ 可以忽略。教材里 PA = LU 的写法要记牢:P 是置换矩阵,满足 PA = LU,用它解方程时是解 LUx = Pb,右端项也要跟着换行。

import numpy as np def pa_lu(A): n = A.shape[0] U = A.astype(float).copy() L = np.eye(n) P = np.eye(n) for k in range(n - 1): p = k + np.argmax(np.abs(U[k:, k])) # 选列主元所在行 if p != k: U[[k, p]] = U[[p, k]] # 交换 U 的行 P[[k, p]] = P[[p, k]] # 记录置换 L[[k, p], :k] = L[[p, k], :k] # L 只交换已算出的前 k 列 for i in range(k + 1, n): L[i, k] = U[i, k] / U[k, k] # 乘子存进 L U[i, k:] -= L[i, k] * U[k, k:] # 行消元 return P, L, U

A必须是方阵。返回的P、L、U满足P @ A == L @ U,L是单位下三角,U是上三角。关键是L[[k, p], :k]这一行:交换 L 时只能动已经算出来的前 k 列,动多了会把后面的乘子搞乱,这是手写 PA=LU 最容易翻车的一行。验证时用np.allclose(P @ A, L @ U),比肉眼看强。

3.4 迭代法与 SPD 矩阵:谱半径判据怎么用

把 A 拆成 D − L − U,Jacobi 的迭代矩阵是 B_J = D⁻¹(L + U),Gauss-Seidel 的是 B_GS = (D − L)⁻¹U,两者收敛的充要条件都是谱半径 ρ(B) < 1。这个判据要写全:谱半径小于 1,不是范数小于 1。用范数判别只是充分条件,题目里如果给了具体矩阵,算谱半径才是标准答法。

严格对角占优是常用的充分条件:每行对角元的绝对值大于该行其余元素绝对值之和,则 Jacobi 和 Gauss-Seidel 都收敛。注意这是充分不必要,反过来不成立,答题时加一句「反之不成立」能避免被判概念混淆。

对称正定矩阵有几个专属结论:Cholesky 分解 A = LLᵀ 存在且唯一,运算量约为高斯消元的一半,还不用选主元;Gauss-Seidel 一定收敛;Jacobi 要看 2D − A 是否也正定。共轭梯度法(CG)是解 SPD 系统的迭代法,每步一次矩阵向量乘,理论上至多 n 步收敛,实际配合预处理能用得更好。这些点经常出成一道「下列哪些方法适用于 SPD 矩阵」的选择或简答,背熟能直接拿分。

3.5 证明题演练:收敛阶的推导骨架

题目:设 r 是不动点,g 在 r 的邻域内连续可微,|g′(r)| < 1,证明不动点迭代 xₖ₊₁ = g(xₖ) 局部收敛且为一阶。

答题骨架分四步。第一步,取 L 满足 |g′(r)| < L < 1,由 g′ 连续,存在 δ 使 |x − r| < δ 时 |g′(x)| ≤ L。第二步,对任意初值落在该邻域内,用中值定理:|xₖ₊₁ − r| = |g(xₖ) − g(r)| = |g′(ξₖ)||xₖ − r| ≤ L|xₖ − r|。第三步,递推得 |xₖ − r| ≤ Lᵏ|x₀ − r| → 0,收敛性得证。第四步,两边除以 |xₖ − r| 得误差比值趋近 |g′(r)|,极限存在且非零,故为一阶收敛。

评分点在哪:中值定理那一步必须有 ξₖ 落在 xₖ 和 r 之间(这决定了要用邻域内的一致界 L,而不是直接写 |g′(r)|);递推那一步要写清指标;最后一阶收敛的结论要从「误差比值极限为非零常数」推出来,只说「线性收敛」不给满分。这道题的变体是「若 g′(r) = 0 且 g″ 连续,证明二阶收敛」,把中值定理换成二阶泰勒展开即可,框架完全一样。

4. 插值、积分与微分方程:误差项和阶数是拿分关键

4.1 多项式插值:唯一性、误差项与 Runge 现象

n+1 个互异节点上的 n 次插值多项式存在且唯一,这一条几乎每次都考,但真正给分的是后半句:唯一性来自线性方程组的系数矩阵是 Vandermonde 矩阵且行列式非零。只说「唯一」不说理由,大概率半分。

误差公式必须默写:f(x) − p(x) = f⁽ⁿ⁺¹⁾(ξ)/(n+1)! · ∏(x − xᵢ),其中 ξ 落在包含所有节点和 x 的最小区间内。三个要素缺一不可——阶数 n+1、除以 (n+1)!、乘积项,其中 ξ 的取值范围是最常被漏的,很多人只写「存在 ξ」,没写它在哪。

Runge 现象是标准反例:f(x) = 1/(1+25x²) 在 [−1,1] 上取等距节点,次数越高端点振荡越厉害。答题要指出振荡来自乘积项 ∏(x − xᵢ) 在端点附近变大,而不是来自 f 本身。这个解释能把 Chebyshev 节点那一节自然接上。

Vandermonde 方程组虽然理论上可解,实际是病态的,条件数随 n 指数增长。所以工程上不会真去解它,而是用 Lagrange 形式或 Newton 差商形式求值——差商表的 O(n²) 复杂度也是常见考点。

4.2 Chebyshev 节点与三次样条:怎么选节点

Chebyshev 多项式 Tₙ(x) = cos(n·arccos x),它在 [−1,1] 上最小化最大模。用它构造插值节点,就是把 Tₙ₊₁ 的根拿来做节点:xₖ

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询