0

I am writing a mortgage calculator that will populate a DataGridView all the payments and how much interest and principal for each payment. Then the last column is the remaining balance after the payment.

Here is the problem:

The Mortgage payment, interest and principal calculations are all good, but for some reason the remaining balance calculation seems wrong because at the end of the payment period there is still a large balance.

My code may be sloppy, because I am still new to vb. In fact it's my first class.


Private Sub AmortButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AmortButton.Click 'initiate click event'
    Dim Amt As Double = Amount.Text() 'read in amount'
    Dim Intr As Double = Intrest.Text() 'read in intrest'
    Dim Yrs As Double = Term.Text() 'read in years'
    Dim payment As Double = (Yrs * 12) 'convert years to payment periods
    '
    Dim IntrDec As Double = ((Intr / 100) / 12) 'convert APR to monthly rate as a decimal'
    Dim TempAmt As Double = Amt 'setting Temperory balance
    For i As Double = 1 To payment Step i + 1 'setting for-loop paramaters'
        Dim MP = Math.Round((Pmt(IntrDec, payment, Amt) * -1), 2) 'calculate Mortgage payment'
        Dim IP = Math.Round((IPmt(IntrDec, i, payment, Amt) * -1), 2) 'calculate Intrest paid'
        Dim PP = Math.Round((PPmt(IntrDec, i, payment, Amt) * -1), 2) 'calculate priciple paid
        Amt = Amt - PP 'setting new balance'
        Dim RM = Math.Round((Amt), 2) 'rounding balance to two decimals'
        AmortTable.Rows.Add(i, MP, IP, PP, RM) 'adding row entry to table'
    Next 'end for-loop'

End Sub

2 Answers2

1

You have a logic error in your loop. You are changing the amount of the loan every time the loop runs

Amt = Amt - PP 'setting new balance'

I notice you have TempAmt declared above the loop, so it looks like you anticipated needing it at some point :); decrement that instead of Amt each time and assign to RM

Also, the STEP i+1 isn't necessary, and while it works here, it's not strictly correct. It will set the loop iteration to whatever the value of i is PLUS 1 when the loop is initialized. Here you're lucky because i defaulted to zero at the beginning. Bottom line, the STEP should be a constant, and since the default is the value 1 you don't need it at all here.

And the advice by paulsm4 is spot on as well, but in a sample like you have you'd likely see small aberrations as a result - a few pennies or so at the end for instance. Floating point arithmetic is undoubtedly a topic you'll get into in a future class.

Jim O'Neil
  • 23,344
  • 7
  • 42
  • 67
  • @O'Neil Yeah, I did forget to change that back. I did try using 'Amt' as a shot at fixing it. I did try changing it back and making the corrections you mentioned, but I still am getting the same error in the remaining amount. I didn't put the IP and PP variables outside the loop because in the IPMT and PPMT function it requires the payment number. Maybe I am using these functions wrong? I do need to say that these are both great words of advice because I did not know that about the auto incrementing variable in the for loop. and also the advice about the floating point arithmetic. – user1599443 Aug 16 '12 at 04:00
  • ah yes, you are correct about IPMT and PPMT needing the payment number - I've edited that out. That said, your code works for me if I simply change Amt to TempAmt in the line with the comment "setting new balance" and the one that follows it – Jim O'Neil Aug 16 '12 at 04:14
  • @O'Neil Yes you are right! I tried it by changing all `Amt`'s to `TempAmt` But once I figured it needed the original loan amount for the PPMT and IPMT functions it was fixed! Thank you for your helpful advice and getting me on the right track! – user1599443 Aug 16 '12 at 04:22
  • glad I could help, turns out you weren't that far off. When you have a chance, could you mark the question as answered? Thanks and good luck with the rest of the course. – Jim O'Neil Aug 16 '12 at 06:02
  • Sorry for the probably obvious question, but this is my first time on stackoverflow. How do I mark it as answered? – user1599443 Aug 17 '12 at 04:26
  • there should be checkbox appearing for you under the up/down arrows next to the start of each answer section. See the FAQ topic here: http://stackoverflow.com/faq#howtoask – Jim O'Neil Aug 17 '12 at 05:03
0

Nothing to do with VB.Net per se.

The problem is that floating point numbers are an "approximation" - you can sometimes encounter "surprising" results when you use them. Similarly, you can also get "surprises" when you mix floating point (e.g. "Intr") and integer (e.g. "Intr / 100").

SUGGESTION:

Try changing "i" and "payment" to "integer", and see if you get any different results.

ALSO:

These links might help:

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • Thank you so much for the quick response! I just tried it in the program and I get the same results... I also tried changing Yrs to integer and I get the same results. I never did know that about floating point numbers. This is good advice. Any other hints that may solve this program? – user1599443 Aug 15 '12 at 05:47
  • Step through the debugger and look at the values. ALSO: perhaps there's simply an ["off-by-one"](http://stackoverflow.com/questions/2939869/what-is-exactly-the-off-by-one-errors-in-the-while-loop) error in the loop. – paulsm4 Aug 15 '12 at 15:37
  • THANK YOU! I didn't know there was that step through debug feature. Going through it really made me see my error. I kept thinking that for the IPMT and PPMT function that it needed the remaining loan balance in the loan variable, but it requires the original loan amount. Thank you and O'Neil! – user1599443 Aug 16 '12 at 04:19