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

计算负IRR时触发ValueError: math domain error的通用解决方案求助

报错根因

这个ValueError: math domain error来自math.pow函数:fsolve是无约束求解器,迭代过程中会尝试i < -1的取值,此时1 + i < 0,对非整数次幂(比如你的场景里的0.99)求幂在实数域无定义,直接触发报错。你之前的临时方案本质是让迭代路径避开了i < -1的区间,没有从根本上解决问题,复杂场景下迭代还是会踩到非法取值。

彻底解决方案

核心做两处改进即可覆盖所有合法IRR求解场景,包括非整数时间节点、负IRR等复杂情况:

  • 替换无约束的fsolve为支持边界约束的求根工具,IRR的合理取值范围是i > -1(折现率不可能低于-100%),直接把求解下边界设为-0.999999(避免取到-1导致除零),从根源上避免迭代到非法区间
  • 给NPV函数增加鲁棒性判断,就算迭代到非法取值也不会触发报错,直接返回超大残差引导求解器回到合法区间
修正后可运行代码
import math
from scipy.optimize import root_scalar
from functools import reduce

dcfs = [0, 0.99]
values = [-100, 50]

def npvFromIrr(i):
    # 先做合法值判断,避免math.pow报错
    if i <= -1:
        # 非法区间返回超大残差,引导求解器往i>-1的方向走
        return 1e18 if i < -1 else 1e9
    return reduce(lambda a, b: a + b, map(lambda x: x[1] / math.pow(1 + i, x[0]), zip(dcfs, values)))

# 用带边界的brentq方法求解,指定IRR的合理范围是-0.999999到10(上限可根据业务调整,10对应1000%的IRR,覆盖绝大多数场景)
sol = root_scalar(npvFromIrr, bracket=[-0.999999, 10], method='brentq')
print(f"IRR计算结果:{sol.root:.2%}")

运行后输出结果约为-50.35%,符合业务预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:57:01