题目
编写一个通用的数值二分法求根器函数 <code>bisection_solve(func_handle, a, b, tol)</code>,能够接收任意传入的目标连续函数句柄 <code>func_handle</code>,在根所在区间 $[a, b]$ 上逐步逼近零点,直到区间长度小于容差 <code>tol</code>。求解方程 $x^3 - x - 2 = 0$ 在 $[1, 2]$ 区间的实根。
输入格式:无需外部输入。
输出格式:输出二分法迭代步数、求得的数值根,以及代入函数的残差。
数据范围与约定:高阶函数与数值求根。
思路与算法
1. 零点存在定理(介值定理)
若连续函数在闭区间端点异号 $f(a) \cdot f(b) < 0$,则区间内必定存在至少一个实根。
2. 函数句柄作为入参
形参 func_handle 接收 @(x) ...。在二分法内部直接像普通函数一样调用 fa = func_handle(a);。
3. 二分步长衰减
每一步将区间中点 $c = (a+b)/2$,每次迭代区间长度严格减半,收敛稳定绝对不发散。
完整程序
% Octave / MATLAB 第67题:函数句柄作为参数传递 (二分求根)
1;
function [root, iter] = bisection_solve(f, a, b, tol)
fa = f(a);
fb = f(b);
if fa * fb > 0
error("区间端点函数值同号,无法保证存在根!");
end
iter = 0;
while (b - a) / 2 > tol
c = (a + b) / 2;
fc = f(c);
if abs(fc) < 1e-12
root = c;
return;
end
if fa * fc < 0
b = c;
fb = fc;
else
a = c;
fa = fc;
end
iter = iter + 1;
end
root = (a + b) / 2;
end
% 目标方程: f(x) = x^3 - x - 2 = 0,在 [1, 2] 内有根
target_f = @(x) x.^3 - x - 2;
[r, steps] = bisection_solve(target_f, 1.0, 2.0, 1e-6);
fprintf("目标函数: f(x) = x^3 - x - 2\n");
fprintf("迭代步数: %d 步\n", steps);
fprintf("求得零点: x = %.6f\n", r);
fprintf("零点处残差 f(x): %.2e\n", target_f(r));运行示例
输出:
目标函数: f(x) = x^3 - x - 2
迭代步数: 19 步
求得零点: x = 1.521380
零点处残差 f(x): 4.27e-06