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

PHP版Excel RATE函数适配逐年递增还款额(pmt)的实现问询

支持递增还款额的PHP版RATE函数实现

原函数仅支持固定还款额的年金利率计算,我们可以通过新增年增长率参数,并替换核心的现值计算公式为增长型年金现值公式,来实现逐年递增还款额的利率计算需求。

修改后的完整代码

function RATE($nper, $pmt, $growth = 0.0, $pv, $fv = 0.0, $type = 0, $guess = 0.1) {
    $financial_max_iterations = 20;
    $financial_precision = 0.00000008;

    $rate = $guess;
    // 计算当前利率下的现金流现值总和(PV + 递增还款现值 + 终值现值)
    $y = calculatePresentValue($nper, $pmt, $growth, $pv, $fv, $type, $rate);
    
    $y0 = calculatePresentValue($nper, $pmt, $growth, $pv, $fv, $type, 0.0);
    $y1 = $y;

    // 割线法迭代求解利率
    $i  = $x0 = 0.0;
    $x1 = $rate;
    while ((abs($y0 - $y1) > $financial_precision) && ($i < $financial_max_iterations)) {
        $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0);
        $x0 = $x1;
        $x1 = $rate;

        $y = calculatePresentValue($nper, $pmt, $growth, $pv, $fv, $type, $rate);

        $y0 = $y1;
        $y1 = $y;
        ++$i;
    }
    return $rate;
}

/**
 * 计算增长型年金的现值总和
 */
function calculatePresentValue($nper, $pmt, $growth, $pv, $fv, $type, $rate) {
    $rateAbs = abs($rate);
    $growthAbs = abs($growth);
    
    // 计算还款额的现值部分
    if ($rateAbs < 0.0000001) {
        // 利率接近0时的简化计算
        if ($growthAbs < 0.0000001) {
            // 无增长,固定还款额
            $pmtPresentValue = $pmt * (1 + $rate * $type) * $nper;
        } else {
            // 利率为0,有增长:求和pmt*(1+g)^t,t从0到nper-1
            $pmtPresentValue = $pmt * ((pow(1 + $growth, $nper) - 1) / $growth) * (1 + $rate * $type);
        }
    } else {
        if (abs($rate - $growth) < 0.0000001) {
            // 利率等于增长率时的简化计算
            $pmtPresentValue = $pmt * (1 + $rate * $type) * $nper * pow(1 + $rate, -$type);
        } else {
            // 通用增长型年金现值公式
            $growthFactor = (1 + $growth) / (1 + $rate);
            $pmtPresentValue = $pmt * (1 + $rate * $type) * (1 - pow($growthFactor, $nper)) / ($rate - $growth);
        }
    }
    
    // 计算终值的现值
    $fvPresentValue = $fv / pow(1 + $rate, $nper);
    
    // 总现值总和 = 初始现值 + 还款现值 + 终值现值
    return $pv + $pmtPresentValue + $fvPresentValue;
}

关键修改说明

  1. 新增参数:加入$growth参数,代表还款额的年增长率(传入小数形式,如10%则传0.1),默认值为0,兼容原函数的固定还款额场景。
  2. 拆分计算逻辑:将现值计算抽离为calculatePresentValue函数,便于维护,同时完整实现了增长型年金的现值计算:
    • 区分利率为0、利率等于增长率、通用情况三种场景,避免除零错误并保证计算精度
    • 保留原函数的type参数(期初/期末还款)逻辑
  3. 保留迭代逻辑:原有的割线法迭代求解逻辑不变,确保利率计算的收敛性和精度。

调用示例

以你提到的场景为例:贷款本金80000元,首年还款1200元,年增幅10%,期限20年,期末还款,计算利率:

// 参数说明:期数nper=20,首年还款pmt=-1200(支出为负),增长率growth=0.1,现值pv=80000(收入为正)
$rate = RATE(20, -1200, 0.1, 80000);
echo "年利率:" . round($rate * 100, 2) . "%";

注意事项

  • 现金流符号规则遵循Excel标准:流入为正,流出为负(如贷款本金是流入,还款是流出)
  • 增长率需传入小数(如5%传0.05),若为负则代表还款额逐年递减
  • 若迭代20次仍未收敛,可适当调整$financial_max_iterations参数增加迭代次数

内容的提问来源于stack exchange,提问作者T.K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:02:45