如何用Python求解参数由用户输入的ax⁴ + bx² + c = 0方程
双二次方程 ax⁴ + bx² + c = 0 的Python求解实现
核心求解逻辑
这类无一次、三次奇次项的四次方程(又称双二次方程)不需要复杂的高次求根算法,通过换元降次即可完成求解,整体流程为:
- 变量替换:令 t = x²,原方程可转换为关于t的一元二次方程
a*t² + b*t + c = 0,把四次问题降为二次问题 - 求解二次方程根:计算二次方程的判别式
Δ = b² - 4ac,分实域、复域场景求出所有t值 - 回代求原方程的解:对每个t值,通过x = ±√t 推导得到原方程的全部实根/复根
边界场景处理
写代码前需要覆盖这些容易引发逻辑错误的场景:
- 系数a的合法性校验:如果a值过小(接近0),原方程会退化为二次/一次方程,不再属于四次方程范畴,需要提前抛出提示避免逻辑混乱
- 实根场景的t值筛选:实数域下t=x²必须满足t≥0,t为负数的解仅能对应复数域的根,不能参与实根输出
- 浮点精度兼容:判断数值是否为0时,不能直接用相等判断,需要设置极小阈值(如1e-9)抵消浮点运算的精度误差
可直接运行的实现代码
import math import cmath def solve_biquadratic(a: float, b: float, c: float): # 校验a是否接近0,避免浮点精度误判 if abs(a) < 1e-9: raise ValueError("系数a不能为0,否则原方程不属于四次方程") roots = [] # 计算t对应二次方程的判别式 delta = b ** 2 - 4 * a * c # 分情况求解t的所有值 if delta >= -1e-9: # 实域范围内的t值 t1 = (-b + math.sqrt(max(delta, 0))) / (2 * a) t2 = (-b - math.sqrt(max(delta, 0))) / (2 * a) t_solutions = [t1, t2] else: # 复域范围内的t值 delta_c = complex(delta, 0) t1 = (-b + cmath.sqrt(delta_c)) / (2 * a) t2 = (-b - cmath.sqrt(delta_c)) / (2 * a) t_solutions = [t1, t2] # 逐个t值回代求x的解 for t in t_solutions: if isinstance(t, complex): # 复数t直接计算复根 x1 = cmath.sqrt(t) roots.extend([x1, -x1]) else: # 实数t仅在t非负时计算实根 if t >= -1e-9: valid_t = max(t, 0) x1 = math.sqrt(valid_t) roots.extend([x1, -x1]) # 对重复的根(重根场景)去重 unique_roots = list(set(roots)) return unique_roots # 对接用户输入的交互逻辑 if __name__ == "__main__": try: a = float(input("请输入系数a: ")) b = float(input("请输入系数b: ")) c = float(input("请输入系数c: ")) solve_result = solve_biquadratic(a, b, c) print(f"方程的所有解为: {solve_result}") except ValueError as e: print(f"运行错误: {e}")
简化实现方案
如果不需要手动校验所有边界场景,也可以借助numpy的内置多项式求根接口快速实现,只需要按照多项式阶次从高到低整理系数:原方程x⁴项系数为a、x³项系数为0、x²项系数为b、x¹项系数为0、常数项为c,组成系数列表
[a, 0, b, 0, c]后直接传入numpy.roots(),即可自动返回复数域下的全部方程解。
内容的提问来源于stack exchange,提问作者Leo1807
相关产品推荐
相关产品推荐

