题目

编写一个通用的数值二分法求根器函数 <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