Loan Amortization

Four parameters are needed to calculate the balance left on a loan:

Initially, the balance equals the principal, but the balance will change over time, as payments are made and interest is added. Each month, there are two things that happen to the loan:

The loan1.cpp program on PUBLIC demonstrates the amortization function. It will ask for the principal, rate, months, and monthly payment, and return the balance at the end of the months. Using this, we can write a new program which can calculate the correct payment, given the principal, rate, and number of months till completion.

First, though, play around with the loan1 program, trying different numbers out. Go on, enjoy yourself. You should notice a couple of things:

(The line is drawn smudgy, because we don't know what the exact shape is, but we do know what general form it will have.)

So now we have some ideas about how to figure out what the payment should be:

Now we need to figure out how to find a payment that is too high. While those of us with loans may be of the opinion that any payment is too high, that isn't a mathematically sound opinion. So what we do is start with principal/months. Then we keep doubling the answer until we find one that's too high. For example, imagine that principal/months = $100. We would check $100, $200, $400, $800, etc. until one was too big. We can also adjust the range as we go through, setting the low marker to whatever the last number that wasn't too high was. So if $800 is the first one that's too high, then rather than check the interval [$100, $800], we should check the interval [$400, $800].

So, how do we go about checking these intervals, once we figure out what they ought to be?

This procedure is known as interval bisection. The demo loan2.cpp on PUBLIC shows how to use this to find the correct payment. Note: The const HALF_PENNY is used to compensate for C++'s way of dealing with too many decimal points, namely that it truncates them, rather than rounding them. We would like to round to the nearest penny, so we add $.005, and that will get the right answer out (e.g., the answer is 1.115 - We would like the answer to be printed as 1.12, but C++ merely chops off the last .005. If we add the half-penny, then the answer becomes 1.120, and 1.12 will be printed, as we would like. Note that it has no effect on an answer such as 1.111, which would become 1.116, and would still be printed as 1.11.

Analysis

How many bisections will need to take place before iunterval size is within a tolerance t? Suppose that the initial interval is (h - l).

# of bisections interval size
0 h-l
1 (h-l)/2
2 ((h-l)/2)/2 = (h-l)/4
3 ((h-l)/4)/2) = (h-l)/8
... ...
n (h-l)/2n

Stop when

         (h-l)/2n < t
                t > (h-l)/2n
               2n > (h-l)/t
       n = log22n > log2((h-l)/2)
                  = log2(h-l) - log2t

Let's do an example of this formula, with l = 600, h = 1200, and t = 0.01.

log2(h-l) = log2600
          = 9.... (29= 512, 210 = 1024)
  log20.01 = -6....(2-6 = 1/64, 2-7=1/128)

therefore, the number of iterations is, at worst, 10-(-7) = 17. If we were to double the interval size, it would take one more iteration, and if we double the tolerances, it would take one less iteration.

It is also possible (and in fact has happened before and will most likely happen again, so you'd better pay attention here) that a problem like this will show up on the first exam:

Which takes more iterations?

Comparing A to B, the interval is 4 times smaller, but the tolerance is 32 times smaller, so A will take 2 fewer iterations than B based on the interval (halving the interval twice), but five more iterations based on the tolerance (doubling the tolerance five times, since 25=32). Therefore, A takes three more iterations in total.

To Index Previous Next