题目
求解一元二次方程 $a x^2 + b x + c = 0$。从标准输入读入 $a, b, c$($a \neq 0$),计算判别式 $\Delta = b^2 - 4ac$。根据 $\Delta > 0$(两不等实根)、$\Delta = 0$(两相等实根)与 $\Delta < 0$(一对共轭复数虚根)分流输出精确解。
输入格式:一行输入 3 个浮点数,分别代表 a, b, c。
输出格式:输出根的类型说明及具体的解数值(虚根按 a ± bi 格式输出)。
数据范围与约定:实数系数,a 不为零。
思路与算法
1. 二次项系数 a 防零
若 $a=0$,方程退化为一元一次方程,必须先防御拦截。
2. 判别式浮点容差
判断重根时,计算机浮点数极难严格等于 0,应使用 abs(delta) < 1e-12。
3. 虚根格式化解析
当 $\Delta < 0$ 时,实部为 $-b/(2a)$,虚部为 $\sqrt{|\Delta|}/(2a)$。虽然 Octave 的 sqrt(delta) 原生支持复数开方,但在分支逻辑中显式按实虚部格式化输出更为清晰。
完整程序
% Octave / MATLAB 第44题:一元二次方程根讨论
[params, count] = scanf("%f", 3);
if count < 3
fprintf("错误:需输入 a, b, c 三个系数。\n");
return;
end
a = params(1);
b = params(2);
c = params(3);
if abs(a) < 1e-12
fprintf("错误:二次项系数 a 不能为 0(方程退化为线性方程)。\n");
return;
end
delta = b^2 - 4 * a * c;
fprintf("判别式 Delta = %.4f\n", delta);
if delta > 1e-12
% 两个不等实根
x1 = (-b + sqrt(delta)) / (2 * a);
x2 = (-b - sqrt(delta)) / (2 * a);
fprintf("情况: 两个不相等实根\n");
fprintf("x1 = %.4f, x2 = %.4f\n", x1, x2);
elseif abs(delta) <= 1e-12
% 两个相等实根 (重根)
x = -b / (2 * a);
fprintf("情况: 两个相等实根 (重根)\n");
fprintf("x1 = x2 = %.4f\n", x);
else
% 一对共轭复数根
real_part = -b / (2 * a);
imag_part = sqrt(-delta) / (2 * a);
fprintf("情况: 一对共轭虚根\n");
fprintf("x1 = %.4f + %.4fi\n", real_part, abs(imag_part));
fprintf("x2 = %.4f - %.4fi\n", real_part, abs(imag_part));
end运行示例
示例 1:
输入:
1 -5 6输出:
判别式 Delta = 1.0000
情况: 两个不相等实根
x1 = 3.0000, x2 = 2.0000示例 2:
输入:
1 -2 1输出:
判别式 Delta = 0.0000
情况: 两个相等实根 (重根)
x1 = x2 = 1.0000示例 3:
输入:
1 2 5输出:
判别式 Delta = -16.0000
情况: 一对共轭虚根
x1 = -1.0000 + 2.0000i
x2 = -1.0000 - 2.0000i