You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二分法求函数根程序报错,进入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))

错误原因分析

  1. 误差更新逻辑错误:代码中error * abs(b - a)是无效的乘法操作,并未将新的区间长度赋值给error,导致error始终保持初始值,循环无法正常终止,还会引发后续逻辑异常。
  2. 区间有效性检查位置错误:将区间两端点函数值乘积检查放在循环内部,每次迭代都执行。但二分法的核心前提是初始区间[a,b]两端点函数值异号,后续迭代中只要逻辑正确,区间两端点必然保持异号,重复检查可能因浮点精度问题误判,甚至触发不必要的退出。
  3. 未处理精确根情况:当计算的中点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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:21:49