2

I'm trying to make a program that will allow the user to determine different aspects when considering a loan. The first equation is supposed to determine what the monthly payment would be given the loan amount, interest rate, and number of months. The second equation is supposed to determine how many payments(or months) one would have to make given the loan amount, interest rate, and monthly payment. This is the code I'm testing with, but I can't seem to get valid output.

    float amount = 20000;
    float rate = (float) 7.5;
    float months = 60;
    float payment = 450;

    float answer = (float) (((amount*(rate/1200))*(1+(Math.pow((rate/1200), months))))/((1+Math.pow((rate/1200), months))-1));
    System.out.println(answer);

    float answer2 = (log(payment/amount)-log((payment/amount)-(rate/1200)))/(log(1+(rate/1200)));
    System.out.println(answer2);

For the first equation, I first kept getting errors because it wanted the answer to be a double and kept telling me that for my rate variable I couldn't convert from double to float, so I had to put in casts. Once I got the errors to go away, I keep getting infinity for an answer.

For the second equation, it keeps saying I can't divide by zero. Does anybody know any solutions to this. When looking online, it seems as though I'm formulated my equations correctly, so I don't know how to make them work.

Also, if anyone would happen to know a good formula for determining the interest rate, that would be so helpful.

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
Haley
  • 41
  • 4
  • 3
    If you're unsure which part of your expression is causing the problem, build the expression bit by bit so that you can examine the intermediate results at every step. – NPE Sep 19 '11 at 13:22
  • My code now reads as this: double amount = 20000; double rate = 7.5; double months = 60; double payment = 450; double answer = (((amount*(rate/1200))*(1+(Math.pow((rate/1200), months))))/((1+Math.pow((rate/1200), months))-1)); System.out.println(answer); double answer2 = (Math.log(payment/amount)-Math.log((payment/amount)-(rate/1200)))/(Math.log(1+(rate/1200))); System.out.println(answer2); And my returned answers are infinity and 52.23012630649508. – Haley Sep 19 '11 at 16:29

3 Answers3

3

You're missing some casts, and log should be Math.log. When I convert everything to double (why are you so insistent on using floats? Using doubles means you won't need to put those casts everywhere) I get the following output:

Infinity
52.23012630649508

Not sure what the second value is supposed to be, but that seems ok; no warnings and no errors. Regarding the first part, you're dividing by zero. Try this:

System.out.println(Math.pow(rate/1200, months));

And you'll get the following tiny tiny number

5.659799424266714E-133

Floating point arithmetic will result in your denominator being zero, since that value +1 will lose precision, thus:

System.out.println(1+Math.pow(rate/1200, months)-1);

Yields 0.0 and your denominator will cause the second result to be infinity.

davin
  • 44,863
  • 9
  • 78
  • 78
  • Yes, I changed everything to double and got the same results as you. How do you propose I go about the first equation, so that I do not have this problem? – Haley Sep 19 '11 at 16:29
  • @Haley, first off remove the `1+Math.pow(...)-1`, like I said, you lose precision, and in any case, any number when adding 1 and then subtracting 1 remains the same, so it's useless. That will at least give you an answer that isn't infinity. – davin Sep 19 '11 at 16:42
2

You should not use float/double or raw integers for monetary values, use BigDecimal instead: http://download.oracle.com/javase/1.4.2/docs/api/java/math/BigDecimal.html

This makes it unnecessary to do that forced double->float cast and i hope the errors disappear. If not then add a comment with your new code please.

Bernd Elkemann
  • 23,242
  • 4
  • 37
  • 66
  • Yes, stick with BigDecimal for any floating point based mathematics. It is the the best way to get more accurate answers. – Chris Aldrich Sep 19 '11 at 13:20
  • 1
    @Chris Aldrich: I think the suggestion to use BigDecimal for **all floatint-point math** is way too general to be good advice. – NPE Sep 19 '11 at 13:24
  • @aix - perhaps you are right. I guess I've just encountered enough situations where I realized that default floating point operations (especially when you are dealing with money) isn't the best with the primitives. BigDecimal was a more accurate way to go. But it also depends with your precision needs as you discuss. I still think it a worthwhile general statement though. – Chris Aldrich Sep 19 '11 at 14:12
0

For the second equation:

float answer2 = (log(payment/amount)-log((payment/amount)-(rate/1200)))/(log(1+(rate/1200)));

The only possible division by zero is if log(1+(rate/1200)) equals 0. This is possible if (rate/1200) returns 0. You might solve this by casting (rate/1200) to a float for both occurences.

Thus:

float answer2 = (log(payment/amount)-log((payment/amount)-((float)(rate/1200))))/(log(1+((float)(rate/1200))));

I think the error lies in the fact that rate/1200 is always 0 because 1200 is an integer and so is the solution of the division.

Maza89
  • 518
  • 4
  • 12