基于PHPExcel的函数RATE()返回的值不正确

基于PHPExcel的函数RATE()返回的值不正确,php,phpexcel,financial,Php,Phpexcel,Financial,在这里找到的RATE()函数的最新版本对我不起作用 我创建了一个新的PHP页面,删掉了那个特定的函数并对其进行了测试,但输出到Excel的结果有很大的不同 <?php define('FINANCIAL_MAX_ITERATIONS', 128); define('FINANCIAL_PRECISION', 1.0e-08); function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { /

在这里找到的RATE()函数的最新版本对我不起作用

我创建了一个新的PHP页面,删掉了那个特定的函数并对其进行了测试,但输出到Excel的结果有很大的不同

<?php
define('FINANCIAL_MAX_ITERATIONS', 128); 
define('FINANCIAL_PRECISION', 1.0e-08); 

function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) {
        //$nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);
        //$pmt  = PHPExcel_Calculation_Functions::flattenSingleValue($pmt);
        //$pv       = PHPExcel_Calculation_Functions::flattenSingleValue($pv);
        //$fv       = (is_null($fv))    ? 0.0   :   PHPExcel_Calculation_Functions::flattenSingleValue($fv);
        //$type = (is_null($type))  ? 0     :   (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);
        //$guess    = (is_null($guess)) ? 0.1   :   PHPExcel_Calculation_Functions::flattenSingleValue($guess);

        $rate = $guess;
        if (abs($rate) < FINANCIAL_PRECISION) {
            $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv;
        } else {
            $f = exp($nper * log(1 + $rate));
            $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;
        }
        $y0 = $pv + $pmt * $nper + $fv;
        $y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;

        // find root by secant method
        $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;
            if (($nper * abs($pmt)) > ($pv - $fv))
                $x1 = abs($x1);

            if (abs($rate) < FINANCIAL_PRECISION) {
                $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv;
            } else {
                $f = exp($nper * log(1 + $rate));
                $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;
            }

            $y0 = $y1;
            $y1 = $y;
            ++$i;
        }
        return $rate;
    }   //  function RATE()

$nper = 180;
$pmt = 6729.045954705334;
$pv = -400000;

$test = RATE($nper, $pmt, $pv);
?>
收益率:00158263127885


有什么想法吗?

我设置了一些静态值,并检查值是否在范围内。在这种情况下,我使用一个$guess,否则我使用另一个$guess。在Excel中,无论$guess和传入的值是多少,它都可以工作。

对于上面的示例,如果我将其设置为0.01或0.02,它就可以工作。然而,这失败了:$pmt=5352.2925170510425:这将产生0.17131087338201,而excel产生00117451282205。最后一个选项在$guess=0.1时正常工作,但不是$guess=0.01或$guess=0.02年,这可能是原因。如果我添加了这个,那么它将在特定的迭代计数中进行$猜测=0.14/12;//利息14%/月/年,然后打电话:$test=利率($nper,$pmt,$pv,0.0,0,$guess);我必须根据输入数据使用特定的时间间隔,然后设置一些静态值并检查值是否在范围内。在这种情况下,我使用一个$guess,否则我使用另一个$guess。这不是最好的解决方案,但至少能产生正确的结果。
=RATE(180;6729,04595470533;-400000)