PHPExcel based function RATE() returning NAN() - php

I have this code: http://pastebin.com/Sd9WKZFr
When i call something like rate(60, -6000, 120000) it returns me a NAN result, but the same function on MS Excel returns me 0,04678.... I have the same problem trying -5000, -4000, -3000 and -2000.
When i debug the code, i see that about the 8/9 iteration, the line number 29 begins to return a NAN result, making all of other results to turn NAN too.
BUT, when i call something like rate(60, -1000, 120000) it returns me a float -0.02044..., exactly the same result of MS Excel.
I have already tryed to convert all of math calculations into BCMath functions, but this way the results of -6000 is wrong (-1.0427... instead of 0,04678...) but using -1000 the result is correct, matching excel's result.
Is there a way to make it work correctly?
Thanks in advance for any useful sight about that.

I'll need to do some tests to ensure that there's no adverse effects in other situations; but the following looks as though it might fix this problem, and certainly calculates the correct rate value for your arguments RATE(60, -6000, 120000) stabilises at 0.046781916422493 in iteration 15.
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 (($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()

I would not suggest using Secant method to find internal rate of return as it consumes more time than other preferred iterative methods such as Newton Raphson method. From the code it seems setting a maximum of 128 iterations is a waste of time
Using Newton Raphson method to find RATE with either of the two TVM equations takes only 3 iterations
TVM Eq. 1: PV(1+i)^N + PMT(1+i*type)[(1+i)^N -1]/i + FV = 0
f(i) = 0 + -6000 * (1 + i * 0) [(1+i)^60 - 1)]/i + 120000 * (1+i)^60
f'(i) = (-6000 * ( 60 * i * (1 + i)^(59+0) - (1 + i)^60) + 1) / (i * i)) + 60 * 120000 * (1+0.05)^59
i0 = 0.05
f(i1) = 120000
f'(i1) = 42430046.1459
i1 = 0.05 - 120000/42430046.1459 = 0.0471718154728
Error Bound = 0.0471718154728 - 0.05 = 0.002828 > 0.000001
i1 = 0.0471718154728
f(i2) = 12884.8972
f'(i2) = 33595275.7358
i2 = 0.0471718154728 - 12884.8972/33595275.7358 = 0.0467882824629
Error Bound = 0.0467882824629 - 0.0471718154728 = 0.000384 > 0.000001
i2 = 0.0467882824629
f(i3) = 206.9714
f'(i3) = 32520602.801
i3 = 0.0467882824629 - 206.9714/32520602.801 = 0.0467819181458
Error Bound = 0.0467819181458 - 0.0467882824629 = 6.0E-6 > 0.000001
i3 = 0.0467819181458
f(i4) = 0.056
f'(i4) = 32503002.4159
i4 = 0.0467819181458 - 0.056/32503002.4159 = 0.0467819164225
Error Bound = 0.0467819164225 - 0.0467819181458 = 0 < 0.000001
IRR = 4.68%
TVM Eq. 2: PV + PMT(1+i*type)[1-{(1+i)^-N}]/i + FV(1+i)^-N = 0
f(i) = 120000 + -6000 * (1 + i * 0) [1 - (1+i)^-60)]/i + 0 * (1+i)^-60
f'(i) = (--6000 * (1+i)^-60 * ((1+i)^60 - 60 * i - 1) /(i*i)) + (0 * -60 * (1+i)^(-60-1))
i0 = 0.05
f(i1) = 6424.2628
f'(i1) = 1886058.972
i1 = 0.05 - 6424.2628/1886058.972 = 0.0465938165535
Error Bound = 0.0465938165535 - 0.05 = 0.003406 > 0.000001
i1 = 0.0465938165535
f(i2) = -394.592
f'(i2) = 2081246.2069
i2 = 0.0465938165535 - -394.592/2081246.2069 = 0.046783410646
Error Bound = 0.046783410646 - 0.0465938165535 = 0.00019 > 0.000001
i2 = 0.046783410646
f(i3) = 3.1258
f'(i3) = 2069722.0554
i3 = 0.046783410646 - 3.1258/2069722.0554 = 0.0467819004105
Error Bound = 0.0467819004105 - 0.046783410646 = 2.0E-6 > 0.000001
i3 = 0.0467819004105
f(i4) = -0.0335
f'(i4) = 2069813.5309
i4 = 0.0467819004105 - -0.0335/2069813.5309 = 0.0467819165937
Error Bound = 0.0467819165937 - 0.0467819004105 = 0 < 0.000001
IRR = 4.68%

Related

Calculating interest rate in PHP with converted Excel RATE Function

I'm having this issue as well - one example works and the next doesn't
Here's my code
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 (($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;
}
$rate = abs(round($rate*100,5));
return $rate;
} // function RATE()
And some examples RATE(60,-1338.88,274775,0,0,0.03200); // works - returns 3.40321
RATE(60,-2415.44,448925,0,0,0.04150); // doesn't work - returns 3.16288 when it should be 4.32
Any ideas? I've tried 4-5 pieces of code that all look similar and this one seems to give me the best results, even though they aren't consistent. I feel the code works, because how could it give me one correct result and the rest aren't??
p.s: I'm a newb at posting here, I've been reading this site for about 5 years though - hope I was thorough enough ;)
Similar question, with good info, but still doesn't solve my problem
Secant method of iteration into PHP
Another good question, but still doesn't do what I need...
Calculating interest rate in PHP

How Can I Use the Excel Rate Function Correctly in PHP?

The last time I posted this question I got spanked by you guys because it was not clear what I was asking…I blew it, sorry. So let me try again.
I am trying to mimic the Excel Rate function in PHP. I did obtain some code that does function correctly for other Excel functions but is erratic with the Rate function.
There are two steps involved:
1. Calculate the payment
PMT($rate/12, $nper*12, $pv, $fv, $type)
$rate = .08 // interest rate
$nper = 30 // loan term in years
$pv = (100000 + 4000) // loan amt + loan fees
$fv = 0
$type = 0
PMT = -$763.12 // my PHP result and Excel result
2. Calculate the rate
RATE($nper, $pmt, $pv, $fv, $type, $guess)
$nper = 360
$pmt = -763.12 // must remain negative in formula
$pv = 100000 // loan amt only (excludes loan fees)
$fv = 0
$type = 0
$guess = 0.09 // excel default is 0.10 but it doesn’t work so I lowered
RATE = 0.00701507 // Excel result (correct)
RATE = 0.0048541 // my PHP result (incorrect)
Okay, here’s the catch. When the interest rate is changed from 0.08 to 0.07 the result is a lower PMT of $691.91 which then makes both RATE’s almost identical.
RATE = 0.0061609831 // Excel
RATE = 0.0061609269 // my PHP
My question is this: Have any of you used the Excel RATE function in PHP? Were you successful then please share your formula with me. Or did you encounter this problem and find a way to fix it then please tell me what you did. Thank you.
Check out this solution:
<?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 = $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;
$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;
}
$nper = 60;
$pmt = 93.22;
$pv = -5000;
$fv = 0;
$type = 0;
$guess = 0.09;
var_dump(RATE($nper, $pmt, $pv, $fv, $guess));
?>
Do you know that in PHP (and some other languages) floor((0.1+0.7)*10) equals 7 and not 8?
I'm pretty sure it is all because of this "nuance": http://php.net/manual/en/language.types.float.php
Instead of using float numbers in your calculations, consider using BCMath functions, which guarantee high precision as all numbers are represented as strings: http://php.net/manual/en/book.bc.php
Related: PHP - Floating Number Precision

Problem with Rate function

Short description:
The rate function calculates the rate neccessary to reach the future value.
nper - number of periods (number of periods)
pmt - payments (every month or year)
pv - present value (the initial amount)
fv - future value (the amount to reach)
Question:
I have used the funtion Rate (php code below) and i have some troubles with it. I use it with the following values:
Wrong
Excel - RATE(228;-196,02;-49005;961546,464646;1;0,05) gives: 0,0119
Php - RATE(228,-196.02,-49005,961546.464646,1,0.05) gives: 0.0022
Good
Excel - RATE(228;-196,02;-49005;161546,464646;1;0,05) gives:0,003
Php - RATE(228,-196.02,-49005,161546.464646,1,0.05) gives:0.003
It looks like that when the difference between $nper, $pv, $pmt and $fv becomes bigger the code goes wrong.
Does anyone know what the problem is? Thanks in advance.
define('FINANCIAL_MAX_ITERATIONS', 128);
define('FINANCIAL_PRECISION', 1.0e-08);
function rate($nper, $pmt, $pv, $fv, $type, $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 (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;
}
The code is using the secant method to find the rate of return, I am not sure why the code is not working properly but a better way to implement the Excel RATE function is done with Newton Raphson Method
I will give you the equation that Excel uses for the TVM functions and you can implement the Newton Raphson method by making function f(x) out of this equation
From there you will need to get a derivative of f(x) namely f'(x) and follow the instructions on this page about IRR. The page describes finding IRR with Newton Raphson method but you can replace function f(x) and f'(x) in the article with the following function
f(x) = PV (1+RATE)^NPER + PMT(1+RATE*TYPE)[{(1+RATE)^NPER-1}/RATE] + FV
Now it is up to you to find f'(x) and use the steps outline for using the Newton Raphson Method
This Excel RATE calculator is implemented in PHP using Newton Raphson method so you can use your test data to see if you get the required results. Do note that this calculator follows the US and UK notation for numbers and period is used to represent decimal point unlike the comma used in Europe

Calling the function in this php code

the code is below, I am trying to call the "RATE" function.
RATE(120, -271.09, 20000) is how it is used in excel, with this code I think it should work the same.
What am I doing wrong? how can I get it to work
My code is here: http://pastebin.com/AbKqc8g1
The code posted at your URL is defining a class structure for whatever your application is. Therefore you would need to create an instance of the class before you call any functions within that class. For example, the following should help get you started:
$financial = new Financial;
$rate = $financial->RATE(120,-271.09,20000);
print_r($rate);
Quite how you are trying to use this within your application is unclear but using the above principle you should start to see some output.
You have to make an instance of this class and then run the RATE method.
<?php
require("class.Financial.php");
$fin = new Financial();
$result = $fin->RATE(120, -271.09, 20000);
echo $result;
?>
# Scott M
here is the function:
/**
* RATE
*
**/
function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1)
{
$rate = $guess;
$i = 0;
$x0 = 0;
$x1 = $rate;
if (abs($rate) < FINANCIAL_ACCURACY) {
$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
while ((abs($y0 - $y1) > FINANCIAL_ACCURACY) && ($i < FINANCIAL_MAX_ITERATIONS))
{
$rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0);
$x0 = $x1;
$x1 = $rate;
if (abs($rate) < FINANCIAL_ACCURACY) {
$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;
}

Recreate Excel RATE function using Newton's Method

I'm working on converting a mortgage calculator in PHP, but I don't necessarily need a PHP solution. I'm looking for the logic needed to replicate the Excel RATE function. I've found a solution which uses bisection, and if worse comes to worse, I use that.
I know someone out there in the interwebs world has knowledge of such a function, so I'd love to have an easy answer instead of creating a solution from scratch.
References:
http://office.microsoft.com/en-us/excel-help/rate-HP005209232.aspx
http://en.wikipedia.org/wiki/Newton%27s_method
Thanks
Implementation of the MS Excel RATE() function using the secant method (a finite difference approximation of Newton's method) taken from 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()
I tried to use the code above, but the results simply aren´t the same as Excel (or Google Spreadsheet).
I dont know if you need to implement this function yet, but in any case, I looked at how this algorithm was built and even though I was not able to access the excel source code (or the google worksheet) I found that this is not a simple calculation. About this math, more can be read here:
https://brownmath.com/bsci/loan.htm#Eq8
The function, in PHP, may be something like this:
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;
}
For Laravel use the same function but you remove define
define('FINANCIAL_MAX_ITERATIONS', 128);
define('FINANCIAL_PRECISION', 1.0e-08);
and financial_max_iterations = 20; -> same excel
The code is:
function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) {
$financial_max_iterations = 20;
$financial_precision = 0.00000008;
$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;
}
it worked for me
TL;DR: Here's a SQL Server version. It doesn't work for some values, and the PHP code above will probably fail for the same values.
LONG ANSWER: I needed a RATE function for SQL Server. Using the PHPExcel answer above, and using https://charlottecredittechnology.blogspot.com/2013/05/sql-2008-excel-like-rate-function-part.html I wrote a SQL Server scalar function:
ALTER function [dbo].[Rate](
#nper integer, #pmt float, #pv float, #fv float, #type bit = 0, #guess float = 0.1
) returns numeric(38,10) as
/*
Calculate the effective interest rate of a sequence of regular payments.
*/
begin
declare #returns numeric(38,10) = 0;
if #type is null set #type = 0;
declare #i integer;
declare #rate float = #guess;
declare #FINANCIAL_MAX_ITERATIONS integer = 100;
declare #FINANCIAL_PRECISION float = 0.0000001;
declare #y float, #y0 float, #y1 float, #f float, #x0 float, #x1 float;
set #rate = #guess;
if Abs(#rate) < #FINANCIAL_PRECISION
begin
set #f = 0;
set #y = #pv * (1+#nper*#rate) + #pmt * (1+#rate*#type) * #nper + #fv;
end
else
begin
set #f = Exp(#nper * Log(1+#rate));
set #y = #pv * #f + #pmt * (1/#rate + #type) * (#f-1) + #fv;
end;
set #y0 = #pv + #pmt * #nper + #fv;
set #y1 = #pv * #f + #pmt * (1/#rate + #type) * (#f-1) + #fv;
-- Newton secant method.
set #i = 0;
set #x0 = 0;
set #x1 = #rate;
while Abs(#y0-#y1) > #FINANCIAL_PRECISION and #i < #FINANCIAL_MAX_ITERATIONS
begin
set #rate = (#y1 * #x0 - #y0 * #x1) / (#y1-#y0);
set #x0 = #x1;
set #x1 = #rate;
if Abs(#rate) < #FINANCIAL_PRECISION
begin
set #y = #pv * (1+#nper*#rate) + #pmt * (1+#rate*#type) * #nper + #fv;
end
else
begin
set #f = Exp(#nper * Log(1+#rate));
set #y = #pv * #f + #pmt * (1/#rate + #type) * (#f-1) + #fv;
end;
set #y0 = #y1;
set #y1 = #y;
set #i = #i + 1;
end;
return Convert(numeric(38,10), #rate);
end;
Unfortunately it does not always work. Here's the results of some tests I put together and checked using Excel:
-- (1) OK
select dbo.RATE(4*12, -200, 8000, 0, default, default) * 12 -- SQL formula
0.0924 (9.24%) -- SQL result
=RATE(4*12, -200, 8000, 0) * 12 -- Excel formula
9.24% -- Excel result
-- (2) OK
select dbo.RATE(12, -1000, 12000, 0, default, default) * 12 -- SQL formula
0 (0%) -- SQL result
=RATE(12, -1000, 12000, 0) * 12 -- Excel formula
0% -- Excel result
-- (3) OK
select dbo.RATE(30, -400, 4000, 0, 1, default) -- SQL formula
0.10496 (10.496%) -- SQL result
=RATE(30, -400, 4000, 0, 1) -- Excel formula
10.4964% -- Excel result
-- (4) OK
select dbo.RATE(120, 28.1, -2400, 0, default, default) -- SQL formula
0.0059905810 (0.599%) -- SQL result
=RATE(120, 28.1, -2400, 0) -- Excel formula
0.5991% -- Excel result
-- (5) OK
select dbo.RATE(10, -1000, 10000, -10000, default, default) -- SQL formula
0.1 (10%) -- SQL result
=RATE(10, -1000, 10000, -10000) -- Excel formula
10% -- Excel result
-- (6) WRONG ANSWER (unless you set #guess to 0.01)
select dbo.RATE(475, -1022.93, 272779.21, 0, default, default) -- SQL formula
0 -- SQL result
=RATE(475, -1022.93, 272779.21, 0, 0) -- Excel formula
0.2716% -- Excel result
-- (7) ERROR
select dbo.RATE(252, -29002.85, 2500000, 0, default, default) -- SQL formula
invalid floating point operation -- SQL result
=RATE(252, -29002.85, 2500000, 0) -- Excel formula
1.0833% -- Excel result
-- (8) OK
select dbo.RATE(24, -46.14, 1000, 0, default, default) -- SQL formula
0.0083244385 (0.83244%) -- SQL result
=RATE(24, -46.14, 1000, 0) -- Excel formula
0.8324% -- Excel result
Tests (7) and (8) were taken from RATE Function from EXCEL in Swift providing different results and look for the answer using the Newton-Raphson method.

Categories