C++ help needed : Some code shown
So, here's the deal: I'm taking a college programming course in C++, and I've got a program where it's supposed to calculate the remaining balance of a loan, with the given inputs of the original loan amount, amount of payment, annual interest rate, term of the loan in years, and how many payments have already been made. (everything except the last two of those are designated as floats)
Here's the important chunk of the code that does all the calculations:
// Translate term of loan from years to months
numOfPayments *= 12;
// Translate Annual Interest Rate into monthly interest rate
interestRate = interestRate / 1200;
// Calculate remaining balance and display
balanceLeft = (paymentAmt * (1 - (pow((1+ interestRate),(paymentNum - numOfPayments))) / interestRate));
cout << "\nBalance After Payment #" << paymentNum << ": $" << fixed << setprecision(2) << balanceLeft << endl << endl;
The program outputs a negative number when I ask it to output the amount left over. So, now I'm stuck. Any C++ programmer types available who wouldn't mind giving me some tips as to what I'm missing in there? When I do these calculations in Excel, they come out with a positive number, so I'm lost.
Many thanks in advance, folks. It's been bugging me all week, and I wanted to see if I could fix it myself before begging for assistance.
I accrue pens like Hefner accrues bimbos. -- duckideva
I agree on the balls. Not a fan of the balls. -- wordsmythe asserting himself in OOC Theater



I assume the math is right, but what are your types?
If they're floats or doubles, you've got literals in the code that that'll become ints, rather than floats. If they're not floats or doubles, they probably should be.
I don't remember the rules for automatic typecasting, so this might not be it, but you might try tacking a ".0" to the end of each number in the code (i.e. 1200 -> 1200.0).
Xbox Live: StaatsM
Oh, d'oh...I hadn't caught that! Thanks. I'll see if that helps tweak my numbers properly.
As for the types, like I'd indicated, everything except for paymentNum and numOfPayments is a float. Those two are both typed as int.
Edit: Nope, still coming up as negative. I'm assuming the math is right, too, since I can't otherwise see how I'm messing up the entry of it. I just keep getting a stupid negative number.
I accrue pens like Hefner accrues bimbos. -- duckideva
I agree on the balls. Not a fan of the balls. -- wordsmythe asserting himself in OOC Theater
Instead of setting balanceLeft to a long series of calculations, try putting each calculation into an individual variable and print them out separately so that you can verify that they'll be what you're expecting.
Regardless, this:
pow((1+ interestRate),(paymentNum - numOfPayments))
will always be over 1 as long as interestRate is over 0. And since that is greater than 1, this:
1 - (pow((1+ interestRate),(paymentNum - numOfPayments)))
will be subtracting from 1 a number greater than 1. This will give you a negative number. Since you then divide by interestRate and multiply by paymentAmt, you will get a negative result if both interestRate and paymentAmt are positive (or both negative).
Fedaykin98 wrote:
What I'm about to say has to do with the style of your code rather than its correctness. I know that's not what you asked for. But bear with me; I point this out because you said you were trying to fix the problem yourself, and I think that if you follow Quintin's advice, you should be able to do just that in no time at all.
It's a great start to learn a language and to begin commenting your code from the get go, and I can see you've done that. I'm glad you put those in there for us to see. You can often think of writing the comments in a program (a procedural one, anyways) as similar to writing a To Do list. In fact, if you can think far enough ahead in advance to be able to write out the entire To Do comments list before you write any code, then a lot of times you'll find that you've done half the work already.
The comments in your program are:
// Translate term of loan from years to months
// Translate Annual Interest Rate into monthly interest rate
// Calculate remaining balance and display
It all sounds simple, but actually, that last comment is hiding a lot of work in it. Just look at how complex that line of code is compared to the others!
If your program was a To Do list for overhauling a a car, it would look kinda like this:
1. Replace the Wiper blades
2. Check the turning signals
3. Remove the engine and replace it with a new one
I recommend breaking that "calculate remaining balance" part down into smaller steps. This is a bit more work, and it means you'll have to come up with intermediate values as you go along. That involves coming up with an appropriate name for each of them as well as a data type. The result of all this extra thought will be much more readable albeit longer code. A long program that works is much much more valuable than a short one that doesn't.
Also, doing this might seem like you're writing a slower program. But again, a slow program that works beats out a fast program that doesn't. Donald Knuth is famous for saying:
Okay, you can have this soapbox back now. Please take a few minutes to try what I said before reading spoiler below!
In Ultima Online I used to poison hams and leave them on the ground in cities for people to pick up and eat. I can't believe how many people thought street ham was a good thing to eat. -Elliottx
Thanks for the tips, Yoyo and Quintin. The professor gave us another week on this one (I'm guessing a lot of people had trouble), so I'm still in the loop.
I'm going to post all my code here, with your tips. However, now when I try to compile, I get this "Id returned 1 exit status" error, and it won't fully compile. It started after I broke down the calculations further, so I don't know what the heck I'm doing wrong. Edit: What I get are a mass of linker errors that I can't decipher, and then at the end, I get a Build Error 1, and that's it.
Anyhow, here's my code, in its entirety (and again, much appreciated):
#include
#include
#include
#include
using namespace std;
int main(int argc, char *argv[])
{
/* This program calculates the balance on a loan after
a certain number of payments.
*/
// Declaration of variables
int paymentNum; // Payment number - INPUT
float paymentAmt; // Amount of payment - INPUT
float interestRate; // Interest rate - INPUT
int numOfPayments; // Number of payments - INPUT
float amtOfLoan; // Original amount of loan - INPUT
float balanceLeft; // Balance left over - CALC & OUTPUT
float powerCalc; // Calculation of "1 - pow(x,y)" section - CALC
float intRatePlusOne; // Calculation of 1 + interest rate - CALC
float paymentsRemaining; // Calculation of number of remaining payments - CALC
// Get inputs
cout << "Original Loan Amount: ";
cin >> amtOfLoan;
cout << "Monthly Payment: ";
cin >> paymentAmt;
cout << "Annual Interest Rate: ";
cin >> interestRate;
cout << "Term of Loan (Years): ";
cin >> numOfPayments;
cout << "Show Balance After Payment #: ";
cin >> paymentNum;
// Translate term of loan from years to months
numOfPayments *= 12;
// Translate Annual Interest Rate into monthly interest rate
interestRate = float(interestRate) / 1200.0;
// Calculate monthly interest rate + 1 raised to the power of (number of payments made - total number of payments)
intRatePlusOne = 1 + interestRate;
// Calculate the number of payments remaining
paymentsRemaining = paymentNum - numOfPayments;
// Calculate the 1 - pow(x,y) section of the equation
powerCalc = 1 - pow(intRatePlusOne, paymentsRemaining);
// Calculate remaining balance
balanceLeft = paymentAmt * (powerCalc/interestRate);
cout << "\nBalance After Payment #" << paymentNum << ": $" << fixed << setprecision(2) << balanceLeft << endl << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
I accrue pens like Hefner accrues bimbos. -- duckideva
I agree on the balls. Not a fan of the balls. -- wordsmythe asserting himself in OOC Theater
What's the compilation error? You should get a line number and descriptive message...
Are you typing that in as you do it? It might be more helpful to cut and paste here (that way you are not inadvertently adding/removing mistakes.)
also, shouldn't you subtract the total # of payments from the number of payments to be calculated?, otherwise the payments Remaining will be a negative number.
"Also, I have four legs and am covered in wool. Baa!" *Legion* reveals his inner furry.
A) I'm copying and pasting...hell, I am *not* retyping all that stuff more than I have to
B) You would think so, but for whatever reason, the formula we were given says to subtract the total number of payments from the payment number we're on. The other kicker is, when I try the formula in Excel, it comes up with something much closer to the right number. So, I think with Yoyo's idea to re-balance the calculations, it should be calculating everything in the right order.
However, my compiler keeps kicking back all these linker errors that make no sense (it looks almost like it can't understand what an 'int' is or something...it's a HUGE list of crap), and so I can't compile the program and run it to see if I've gotten the hang of it or not.
I accrue pens like Hefner accrues bimbos. -- duckideva
I agree on the balls. Not a fan of the balls. -- wordsmythe asserting himself in OOC Theater
Linker errors? That's pretty interesting. It would mean that it went through the compilation stage just fine, but then when it tried to find the right libraries for the functions used in the program, it got confused.
But it's hard to diagnose a problem like this without more details - there's a myriad things that could cause linker errors...
Rubb Ed, I'd like to comment on the mathematics, if I may:
The outstanding amount calculated by your program will only be correct if the payment entered is actually the payment that will zeroise the loan (including its interest) after the full term. If you would like to be able to specify any payment you'll have to look at the problem in reverse, ie "How many payments have I made?" instead of "How many payments do I have left?"
EDIT: Just to be clear, subtracting the total number of payments from the number of payments made so far is correct. The formula being employed is a standard term certain annuity formula and relies on the number being negative.
Swing harder! Swing harder!
-- Lilarcor, Baldur's Gate 2
The second batch of code (minus the break statement) compiles just fine for me, one thing that "system("PAUSE"):" call wont work cross platform (if you are specifically doing it for windows you are fine, otherwise use "cin.get();")
Also in your original code snippet you had a precidence issue:
is not the same as:
it is the same as
just like in normal math * & / come before + & -, but after () & ^
"Also, I have four legs and am covered in wool. Baa!" *Legion* reveals his inner furry.
Which compiler are you using? It builds and runs fine in VC6 for me.
Good job commenting your code and using descriptive variable names. I find that it helps me to use notation on my variables as well (for instance, int paymentNum becomes int iPaymentNum) so that you don't have to keep going back to your declarations if you forget the data type. A lot of people use Hungarian Notation, and most professionals see it enough to recognize it whether they use it or not.
Also, if you want a variable that never falls below zero, use the unsigned keyword. I would write out your first variable as:
unsigned int uiPaymentNum;
Another thing:
is a great opportunity to learn why they call it C++. Use the ++ operator and score more style points.
I never minded piracy. Anyone who minds about piracy is full of sh*t. Anyone who pirates your game wasn't going to buy it anyway! -Warren Spector
Got it...once I made those switches to that last set of code, and ran it through a different compiler (was using Dev-C++, switched to TextPad and a Borland C++ compiler), all's well.
Nos, I was wondering if maybe my math was going strange on me the first go around...would explain all the problems I was having.
Minase, regarding the commenting and such, my teacher this semester isn't a stickler for it, but next semester, my professor will kick my ever loving butt around the school twice if I don't do exactly what I'm doing now (at least by reputation she will), so I figure it's better to just get it ingrained in my head now. She wrote the textbooks we're using, so if she says to comment liberally, I shall comment liberally with pleasure. (Helps me out, too, so I don't go back later and go "huh?")
Also, with your other suggestions, we haven't touched upon unsigned yet, but that's a cool one to know, so I'll file that away in my mind for a bit. No talk about Hungarian Notation in the text, so I haven't done that. I'll check with her on that, though.
Finally, I'm guessing I should've written intRatePlusOne = interestRate++...d'oh. I knew that...
Thanks, all, for your help. Much, MUCH appreciated.
I accrue pens like Hefner accrues bimbos. -- duckideva
I agree on the balls. Not a fan of the balls. -- wordsmythe asserting himself in OOC Theater
I sugest you don't use the ++ operator if you don't know what it means . There are two ++ operators and each one returns a different value.
a++ is the same as {int temp=a; a=a+1; return temp;}
++a is the same as { a=a+1; return a};
I think they are called Post-increment and Pre-increment operators . Those things can cause bugs. They also make code less readable if used in an expression .
I know about them, and I even somewhat remember when to use which one. I just hadn't thought about it at that point when I was first writing the program.
Personally, I'm not really keen on using them outside of loops, or other places where iteration is necessary, but that's me. On the other hand, I'll use += and its relatives until the cows come home, since it saves a lot of time and typing.
I accrue pens like Hefner accrues bimbos. -- duckideva
I agree on the balls. Not a fan of the balls. -- wordsmythe asserting himself in OOC Theater