Функция RATE() на основе PHPExcel возвращает неверное значение

Самая новая версия находится здесь: https://phpexcel.codeplex.com/SourceControl/latest#trunk/Classes/PHPExcel/Calculation/Financial.php функции 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);
?>

Вызов функции выше дает: 0,008774735218308

Эксель 2013:

=RATE(180;6729,04595470533;-400000)

Выходы: 0,0158263127885

Есть идеи?


person Patrick    schedule 11.02.2015    source источник
comment
Это работает в приведенном выше примере, если я установил его на 0,01 или 0,02. Однако тогда это терпит неудачу: $pmt = 5352,2925170510425: это дает 0,17131087338201 и превосходит: 0,0117451282205. Последнее работает корректно с $guess = 0,1, но не с $guess = 0,01 или $guess = 0,02.   -  person Patrick    schedule 11.02.2015
comment
Да это может быть причиной. Если я добавлю это, то мне удастся сделать это в течение определенного количества итераций. $ предположение = 0,14/12; // Проценты 14% в месяц в год, а затем сделайте вызов: $test = RATE($nper, $pmt, $pv, 0.0, 0, $guess);   -  person Patrick    schedule 11.02.2015
comment
Мне пришлось использовать определенные интервалы в зависимости от входных данных, чтобы это сработало.   -  person Patrick    schedule 19.03.2015
comment
Я установил некоторые статические значения и проверил, находится ли значение в пределах. В этом случае я использую одну $догадку, иначе я использую другую $догадку. Это не лучшее из решений, но, по крайней мере, оно дает правильный результат.   -  person Patrick    schedule 16.04.2015


Ответы (1)


Я установил некоторые статические значения и проверил, находится ли значение в пределах. В этом случае я использую одну $догадку, иначе я использую другую $догадку. В Excel это работает независимо от $guess и переданных значений.

person Patrick    schedule 16.04.2015