二分法求函数根程序报错,进入else分支如何解决?
二分法求根程序报错问题解决
问题描述
编写二分法求解函数根的程序时,运行触发something went wrong提示,程序无法进入预期的if/elif分支。原代码如下:
import numpy as np import sys def min_bisect(func, a, b, error_accept): def f(x): f = eval(func) return f error = abs(b - a) while error > error_accept: c =(b + a)/2 if f(a) * f(b) >= 0: print("no roots present") sys.exit() elif f(c) * f(a) < 0: b = c error * abs(b - a) elif f(c) * f(b) < 0: a = c error * abs(b - a) else: print("something went wrong") sys.exit() print("the error is " , error ) print("the lower boudary, a, is " , a , ". the upper boundary is b, is " , b) min_bisect("np.exp(x)-(4*x)" , 0 , 1 , (0.0001))
错误原因分析
- 误差更新逻辑错误:代码中
error * abs(b - a)是无效的乘法操作,并未将新的区间长度赋值给error,导致error始终保持初始值,循环无法正常终止,还会引发后续逻辑异常。 - 区间有效性检查位置错误:将区间两端点函数值乘积检查放在循环内部,每次迭代都执行。但二分法的核心前提是初始区间
[a,b]两端点函数值异号,后续迭代中只要逻辑正确,区间两端点必然保持异号,重复检查可能因浮点精度问题误判,甚至触发不必要的退出。 - 未处理精确根情况:当计算的中点
c恰好是函数根时,f(c)=0,此时f(c)*f(a)和f(c)*f(b)均为0,不满足两个elif的<0条件,直接进入else分支触发错误提示。
修正后的代码
import numpy as np import sys def min_bisect(func, a, b, error_accept): def f(x): return eval(func) # 初始区间有效性检查,仅执行一次 if f(a) * f(b) >= 0: print("区间[a,b]内无实根或存在偶数个根") sys.exit() error = abs(b - a) while error > error_accept: c = (b + a) / 2 fc = f(c) fa = f(a) fb = f(b) if fc == 0: # 找到精确根,直接终止循环 a = b = c error = 0 break elif fc * fa < 0: b = c elif fc * fb < 0: a = c else: print("出现未知错误") sys.exit() # 更新当前区间的误差值 error = abs(b - a) print(f"误差为: {error}") print(f"下界a为: {a}, 上界b为: {b}") print(f"近似根为: {(a + b)/2}") min_bisect("np.exp(x)-(4*x)" , 0 , 1 , 0.0001)
修正说明
- 将区间有效性检查移至循环前,确保初始输入符合二分法要求,避免重复检查导致的误判。
- 修正误差更新逻辑,改为
error = abs(b - a),每次迭代后更新当前区间长度作为新的误差值。 - 增加精确根判断分支,当
f(c)=0时直接将区间收缩到精确根,终止循环,避免进入错误分支。 - 提前计算各点函数值,减少重复调用
eval的次数,提升代码效率。 - 使用f-string格式化输出,优化输出可读性。
内容的提问来源于stack exchange,提问作者lisa andersson
相关产品推荐
相关产品推荐

