Using the compound interest formula

I’m going to try and approach this from first principles. I don’t understand much about the calculations, so we need to take this slow.

This all seems to come from the compound interest formula A = P(1 + r/n) ^ (n*t) where:

  • A = final amount
  • P = initial principal
  • r = interest rate
  • n = number of times applied per time period
  • t = number of time periods

where in the working example that I have, A is 2000, P is 1300, r is 9%, n is 12, and t is the number of years.

Because t is the unknown we are interested in, we need to calculate what is t.

We end up with the following formula:
2000 = 1300 * (1 + 0.09 / 12) ^ (12 * t)
and need to solve for t.

Dividing by 1300 gives us:
2000/1300 = (1 + 0.09 / 12) ^ (12 * t)

Moving the plus to the numerator gives us:
2000/1300 = ((12+0.09) / 12) ^ (12 * t)

We can now take the natural log of both sides, which gives:
log(2000/1300) = log(((12+0.09) / 12) ^ (12 * t))

Why that helps, is we can now move the power part to the front of the log:
log(2000/1300) = (12 * t) * log((12+0.09) / 12)

And we can then solve for t
log(2000/1300) / (12 * log((12+0.09) / 12)) = t

That should give us about 4 years, and when working this out in the browser console, I see:

> Math.log(2000/1300) / (12 * Math.log((12+0.09) / 12))
4.804403780771735

So we seem to be on the right track. We now have a formula for calculating the number of years of compounding interest.

Next up is to compare it with the formula that you are using, and to investigate what happens when we use a million dollars.

image

Am I on the right track so far?

2 Likes

Moving that code into your example, I get the following:

var principal = 2000;
var payment = 1300;
var interest = 0.09;
var rate = 12;
var nper1 = Math.log(principal/payment) / (rate * Math.log((rate + interest) / rate))
alert(nper1);

That also gives 4.8 years, which matches up with the expected value.

Setting the interest to 1 percent we get 43 years.

Lowering the payment to 1000 gives us 69 years.

Increasing the principal to 1 million gives us 691 years.

I see in your code that you set the principal to 10 million. My formula gives 921 years for that.

I don’t care to understand why the original formula failed, because we now have a working formula from first steps that works even with 10 million dollars.

var principal = 10000000;
var payment = 1000;
var interest = 0.01;
var rate = 12;
var nper1 = Math.log(principal/payment) / (rate * Math.log((rate + interest) / rate))
alert(nper1);

https://jsfiddle.net/7yL0jw9s/

Enjoy.

1 Like

Thank you!
So this single line replaces the original calculation logic that’s 7 lines?
Then I should convert the decimal numbers from decimal to duodecimal as month, shouldn’t I?

If you mean the interest, I recommend leaving that as a decimal fraction in the code as that’s the most reliable way to understand it.

If your form uses “9” for 9 percent, then just have the code divide by 100 for the interest.

I don’t understand what you mean there. Can you give an example?

The result for $10000000 principal returns
921.4177481015016 years
In order to show the months of the term, I should convert 0.4177481015016 to duodecimal, shouldn’t I?

I would’ve thought that you just multiply 921.4177 by 12, to go from years to the number of months.

I don’t understand what you mean by duodecimal, as I haven’t come across that before.

Oh right, understanding just came to me.

You want to show the result as a number of years and the remaining number months.

Ah, I see.

Yes, output of the original code is like this.
So I need to separate years and months.

period=nyear+" Year(s) and "+nmonth+" Month(s)";

Here is an update that gives the number of years and months, using ceil to round up the number of months.

var years = parseInt(nper1);
var months = Math.ceil((nper1 - years) * 12);
alert(years + " years, " + months + " months");

https://jsfiddle.net/9a4nov6p/

1 Like

Great!

I’ve just tried looking up duodecimal and I’m even more confused than before. Thank goodness we didn’t get lost by going down that rabbit hole.

image

2 Likes

Sorry, I call the number system of hour/month/dozen “duodecimal.”
It wasn’t proper word, I think.

I found an edge-case where payment of $1001 gives 12 for the rounded-up number of months.
https://jsfiddle.net/o4knurqz/

We can check for that and update the values:

var years = parseInt(nper1);
var months = Math.ceil((nper1 - years) * 12);
if (months === 12) {
  years += 1;
  months = 0;
}

https://jsfiddle.net/o4knurqz/1/

which works until better way way to calculate that comes along.

1 Like

A solution without the if statement is to first figure out the rounded-up total number of months, then to get the years and months from that rounded-up figure.

var totalMonths = Math.ceil(nper1 * 12);
var years = parseInt(totalMonths / 12);
var months = totalMonths - years * 12;
alert(years + " years, " + months + " months");

https://jsfiddle.net/o4knurqz/3/

This is the process of “get is working”, then “make it better”.
Which is otherwise known of as refactoring :slight_smile: