2010-07-07 20 views
6

Tôi đang làm việc để chuyển đổi một máy tính thế chấp bằng PHP, nhưng tôi không nhất thiết cần một giải pháp PHP. Tôi đang tìm logic cần thiết để nhân rộng hàm Excel RATE. Tôi đã tìm thấy một giải pháp sử dụng bisection, và nếu tồi tệ hơn đến tồi tệ hơn, tôi sử dụng nó.Tái tạo hàm Excel RATE bằng phương pháp Newton

Tôi biết ai đó ở đó trong thế giới interwebs có kiến ​​thức về chức năng như vậy, vì vậy tôi muốn có câu trả lời dễ dàng thay vì tạo giải pháp từ đầu.

Tài liệu tham khảo:

Cảm ơn

Trả lời

8

Thực hiện các MS Excel SUẤT() chức năng sử dụng phương pháp cát tuyến (một sự khác biệt xấp xỉ hữu hạn của phương pháp Newton) được lấy từ PHPExcel:

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 = $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 (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() 
+2

hoàn hảo hoàn hảo! Chỉ cần nhớ mọi người cắm một số câu lệnh DEFINE cho FINANCIAL_PRECISION và FINANCIAL_MAX_ITERATIONS - hoặc - thay thế chúng bằng các giá trị tĩnh này 0,0000001 và 20 tương ứng. Tôi đã tìm thấy các giá trị này trên trang web MS được tham chiếu ở trên. – Exit

+0

Phương pháp này có vấn đề hội tụ, xem https://stackoverflow.com/questions/14031208/apache-poi-rate-formula-inconsistency-with-long-periods – sled

+0

@Exit - Sau đó có lẽ bạn sẽ quan tâm để cung cấp giải pháp tốt hơn , chia sẻ kiến ​​thức của bạn sẽ mang lại lợi ích cho chúng tôi tất cả –

0

Tôi đã cố gắng sử dụng mã ở trên, nhưng kết quả chỉ đơn giản là không giống như Excel (hoặc Bảng tính Google).

Tôi không biết nếu bạn cần triển khai chức năng này chưa, nhưng trong mọi trường hợp, tôi đã xem thuật toán này được xây dựng như thế nào và mặc dù tôi không thể truy cập mã nguồn excel (hoặc bảng tính google) rằng đây không phải là một phép tính đơn giản. Về toán học này, hơn có thể được đọc ở đây:

https://brownmath.com/bsci/loan.htm#Eq8

Chức năng, trong PHP, có thể là một cái gì đó như thế này:

function rate($nprest, $vlrparc, $vp, $guess = 0.25) { 
    $maxit = 100; 
    $precision = 14; 
    $guess = round($guess,$precision); 
    for ($i=0 ; $i<$maxit ; $i++) { 
     $divdnd = $vlrparc - ($vlrparc * (pow(1 + $guess , -$nprest))) - ($vp * $guess); 
     $divisor = $nprest * $vlrparc * pow(1 + $guess , (-$nprest - 1)) - $vp; 
     $newguess = $guess - ($divdnd/$divisor); 
     $newguess = round($newguess, $precision); 
     if ($newguess == $guess) { 
      return $newguess; 
     } else { 
      $guess = $newguess; 
     } 
    } 
    return null; 
} 
Các vấn đề liên quan