题目
利用牛顿-拉夫逊(Newton-Raphson)迭代法求解非线性方程 $f(x) = x^2 - a = 0$ 的正根(即求 $\sqrt{a}$)。给定初值 $x_0 = a/2$,迭代公式为 $x_{k+1} = \frac{1}{2}(x_k + \frac{a}{x_k})$,设定收敛精度 $\epsilon = 10^{-10}$ 与最大迭代次数,循环求解并与内置 <code>sqrt</code> 比较。
输入格式:一行输入一个正数 a。
输出格式:分行输出迭代步数、牛顿法结果、内置 sqrt 结果及绝对误差。
数据范围与约定:a > 0。
思路与算法
1. 牛顿法数学递推
一阶泰勒展开推导迭代式:$x_{k+1} = x_k - \frac{f(x_k)}{f'(x_k)}$。对于 $f(x) = x^2 - a$,导数 $f'(x) = 2x$,化简即为著名的巴比伦平方根迭代式。
2. 双重循环安全防死循环
数值算法中的 while 循环必须同时配备两个终止条件:① 误差收敛 abs(x_new - x) < tol;② 最大迭代次数 iter < max_iter,防止因方程奇异发散引发死循环。
3. 二次收敛速度
牛顿法在根附近具有二次收敛性,通常 5~8 次即可达到机器精度。
完整程序
% Octave / MATLAB 第56题:牛顿迭代法求平方根
[a, count] = scanf("%f", 1);
if count < 1 || a <= 0
fprintf("错误:请输入大于 0 的正数。\n");
return;
end
x = a / 2; % 初始猜测
tol = 1e-10;
max_iter = 100;
iter = 0;
while iter < max_iter
x_new = 0.5 * (x + a / x);
iter = iter + 1;
if abs(x_new - x) < tol
x = x_new;
break;
end
x = x_new;
end
fprintf("求解 sqrt(%.4f):\n", a);
fprintf("迭代次数: %d 步\n", iter);
fprintf("牛顿法求得根: %.10f\n", x);
fprintf("内置 sqrt 结果: %.10f\n", sqrt(a));
fprintf("绝对误差: %.2e\n", abs(x - sqrt(a)));运行示例
示例 1:
输入:
2输出:
求解 sqrt(2.0000):
迭代次数: 5 步
牛顿法求得根: 1.4142135624
内置 sqrt 结果: 1.4142135624
绝对误差: 2.22e-16示例 2:
输入:
100输出:
求解 sqrt(100.0000):
迭代次数: 8 步
牛顿法求得根: 10.0000000000
内置 sqrt 结果: 10.0000000000
绝对误差: 0.00e+00