1

I made this program in C++, simple calculation of an interest rate of a bank a while back as part of a homework assignment. The answer is incorrect by a small margin but I still cannot understand why, and the mistake gets higher as I try higher input numbers... The instructions on how to get this problem are commented as first lines of the program.

I tried switching the involved variables from float to double then to long double and its still the same answer...

Can anyone please figure out why?

// Homework 2 Task 1.cpp : Show bank balance after loan with user-input factors
//Try the code with 100 deposited sum, 5% interest and 3 months total time
//The answer will show 302.087 whereas the true answer should be 302.507

#include "stdafx.h"
#include <iostream>
using namespace std;

long double compoundVal(unsigned int, unsigned short int, unsigned short int);

void main()
{
    unsigned int DepSum;
    unsigned short int IntRate, NrMonths;
    cout << "Please enther the amount you expect to deposit each month: ";
    cin >> DepSum;
    cout << "\nThe amount of money that you will have in your account after 6 months with Inte-rest Rate of 5% will be: "<<compoundVal(DepSum, 5, 6); //Answering the first part of this task, where the user has to specify the Deposit Sum, and will receive the amount after 6 months with interest of 5%
    cout << "\n\nYou can also see the account balance with interest rate and number of months of your choice.\nPlease enter the Interest Rate of your choice: ";
    cin >> IntRate;
    cout << "\nNow enter the number of months you intend to have the account: ";
    cin >> NrMonths;
    cout << "\nThis will be your account balance: " << compoundVal(DepSum, IntRate, NrMonths) << endl;
}

long double compoundVal(unsigned int d, unsigned short int i, unsigned short int n){
    long double c = (1.0 + (i / 1200.0));   //Finding the monthly percentage, and because the user inputs the yearly interest in %, we need to remove the %(*0.01) and /12 for 12 months/year.
    return((1.0 + (n - 1)*c)*d*c);      //The math formula that will give us the results of the calculation. 
}
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 8
    [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Borgleader Jan 15 '15 at 17:58
  • possible duplicate of [Floating point inaccuracy examples](http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples) – Borgleader Jan 15 '15 at 17:59
  • 2
    Side note: `void main()` is not correct –  Jan 15 '15 at 18:01
  • 4
    I doubt this is the usual floating point accuracy problem, the math is too simple and the difference too large. – Mark Ransom Jan 15 '15 at 18:01
  • @MarkRansom Maybe he's compiling with --fast-math or something? Would that make it worse? – Borgleader Jan 15 '15 at 18:04
  • Try breaking the calculation to smaller steps and follow it with a debugger, you could be missing an implicit int cast somewhere, or having a wrong operator precedence – Leeor Jan 15 '15 at 18:06
  • @Borgleader no it would not. I suspect the steps followed on the calculator aren't identical to the code shown here, but that's going to be impossible to determine. – Mark Ransom Jan 15 '15 at 18:06
  • When I evaluate this expression using a calculator I get 302.0868055555556, which agrees with the answer produced by this code, so I'm going to go with the problem being either (1) the formula in the code is an incorrect implementation of the original formula, or (2) you didn't evaluate it correctly on your calculator. – cdhowie Jan 15 '15 at 18:07
  • Can you provide a table for us? Like `Input`, `Expected Output`, and `Actual Output`? – Icemanind Jan 15 '15 at 18:13
  • 1
    This could quite possibly be the difference between continuous compounding interest and daily/weekly/monthly compounding. There are different formulas for each. In particular, monthly compounding gives the $302.5069 answer... – twalberg Jan 15 '15 at 18:14
  • For better accuracy, the financial institutions recommend using Fixed Point Arithmetic. The base could be 10e-6 of a dollar. A 32-bit integer should still be able to handle most operations. – Thomas Matthews Jan 15 '15 at 18:33

2 Answers2

3

The formula you are using appears to be wrong - but I'm not sure where you got it or what it actually represents. The expected answer is for simple periodic compounding interest. In other words, each month you calculate newbalance = balance * (1 + annualrate/12) + deposit). Iterating that 3 times for your required three months gives the expected answer of $302.5069, instead of the lower value $302.0868 you get from your formula.

twalberg
  • 59,951
  • 11
  • 89
  • 84
  • Are you suggesting using a loop to iterate? I figured the formula out myself, and it took me a long time. I used the formula because I couldn't use a loop to solve the exercise as we hadn't studied them yet and I had no idea how to solve it otherwise.. –  Jan 16 '15 at 14:59
  • No, not necessarily. Iterating would be the naive, but easy to understand, approach. But, especially for long periods, it takes longer than it needs to. As @RSahu demonstrates in his answer, you can derive a closed-form formula to calculate it without iterating, but the derived formula does not match what you came up with, so it's quite possible you had some errors in your derivation... – twalberg Jan 16 '15 at 15:07
1

The formula you are using is wrong.

The value of the first month's deposit at the end of 3 months: d.c^3
The value of the second month's deposit at the end of 3 months: d.c^2
The value of the third month's deposit at the end of 3 months: d.c

If you generalize it to N months, the total value of your deposit at the end of N months will be:

d(c + c^2 + c^3 + ... + c^N)

The value of that sum is: d.c.(c^N - 1)/(c-1)

If you plugin this formula you'll get the correct answer: 302.507.

The formula

sum = d(c + c^2 + c^3 + ... + c^N)

Multiplying both side by c,

sum.c = d(c^2 + c^3 + c^4 + ... + c^(N+1))

Subtracting the two equations,

sum(c-1) = d(c^(N+1) - c) = d.c(c^N - 1)
sum = d.c(c^N - 1)/(c-1)
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Your formula is correct, but did you figure it out yourself or was I supposed to know it from somewhere? Because I figured out the current formula myself, as we hadn't studied loops, and I had no other idea other than a general math formula such as this.. –  Jan 16 '15 at 15:07