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

如何传递函数作为参数?牛顿法求π遇索引越界错误求助

问题分析与修正方案

原代码核心错误点

  • 参数传递错误:调用newton(3,math.sin(3),0.000001)时,第二个参数传的是math.sin(3)的计算结果(数值),但需要传入的是函数对象math.sin。
  • 循环条件逻辑颠倒:原代码while abs(A[n]-A[n-1])<=err,意思是误差达标后仍继续迭代,完全搞反逻辑,应该是误差大于允许值时才继续迭代。
  • 列表索引越界:初始A = [x0],n=1时直接访问A[n](即A[1]),但此时列表仅1个元素,必然触发IndexError。
  • 错误的函数调用:math.f(x0)是错误写法,math模块不存在f函数,应直接使用传入的函数参数f。
  • 冗余递归逻辑:牛顿法是迭代算法,无需递归调用自身,原else分支的递归完全错误,会导致逻辑混乱。
  • 导数实现低效:原deriv返回lambda的写法冗余,且单侧差分精度较低。

修正后的代码

import math

# 数值求导:用中心差分计算f在x点的导数值,精度更高
def deriv(f, x):
    h = 1e-5 
    return (f(x + h) - f(x - h)) / (2 * h)

def newton(x0, f, err):
    A = [x0]
    while True:
        # 取当前迭代的最后一个值计算
        current_x = A[-1]
        fx = f(current_x)
        fpx = deriv(f, current_x)
        # 牛顿迭代公式
        next_x = current_x - fx / fpx
        A.append(next_x)
        # 误差达标则终止迭代
        if abs(next_x - current_x) <= err:
            break
    return A, A[-1]

# 求π的近似值:sin(π)=0,找sin(x)=0在x=3附近的根
approximations, pi_approx = newton(3, math.sin, 1e-6)
print("迭代过程:", approximations)
print("π的近似值:", pi_approx)

关键修改说明

  • 导数函数改为直接返回当前点的导数值,用中心差分替代单侧差分,精度提升。
  • 迭代逻辑改为基于列表最后一个元素计算,彻底避免索引越界问题。
  • 移除冗余的lambda和递归写法,逻辑更简洁直观。
  • 修正参数传递,传入math.sin函数对象而非数值。
  • 循环条件改为当迭代误差小于等于允许值时终止,符合牛顿法迭代终止逻辑。

内容的提问来源于stack exchange,提问作者user996159

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:39:51