Reputation: 21
I have created a loan payment calculator. Whenever I type in any input the output shows up as NaN. Any ideas to what I could change. The first section of code is the main method. The second is another class.
MAIN METHOD
import java.util.Scanner;
public class Assignment8 {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
System.out.print("Enter the amount borrowed: ");
double amountBorrowed = kbd.nextDouble();
System.out.print("Enter the interest rate: ");
int intRate = kbd.nextInt();
System.out.print("Enter the minimum length of loan: ");
int minLength = kbd.nextInt();
System.out.print("Enter the maximum length of loan: ");
int loanLength = kbd.nextInt();
while (loanLength < minLength) {
System.out.println("Invalid input: Input must be greater than minimum length of loan");
System.out.println("Enter the maximum length of loan: ");
loanLength = kbd.nextInt();
}
for (int i = minLength; i <= loanLength; i++) {
double payment = LoanCalc.monthlyPayment(amountBorrowed,loanLength, intRate);
System.out.println(payment);
}
}
}
CLASS
public class LoanCalc {
public static double monthlyPayment(double amountBorrowed, int loanLength, int intRate) {
double interestRate;
double monthlyPayment;
interestRate = intRate / 100 / 12;
monthlyPayment = (interestRate * amountBorrowed) / (1- Math.pow((1 + interestRate) , - loanLength * 12 ));
return monthlyPayment;
}
}
Upvotes: 0
Views: 4585
Reputation: 61975
My first hunch would be NaN is being introduced in Math.pow as has a huge list of conditions that will make it return NaN - see what the actual input values are.
And, now about the actual values - the interestRate
will be wrong (and likely 0) because integer division is being done. Try:
interestRate = (double)intRate / 100 / 12;
Upvotes: 2
Reputation: 106508
The expression interestRate = intRate / 100 / 12
is performing integer division. None of those dividends/divisors are converted to a decimal value, so you get 0.
That makes this expression interesting:
Math.pow((1 + interestRate) , - loanLength * 12 )
The result of that is 1 (since 1 to any power is always 1). You subtract 1 from that to get 0.
Now, something interesting happens when you divide by zero in an IEEE 754 floating point value - you get NaN
.
The result of a floating-point division is determined by the rules of IEEE 754 arithmetic:
If either operand is NaN, the result is NaN.
If the result is not NaN, the sign of the result is positive if both operands have the same sign, and negative if the operands have different signs.
Division of an infinity by an infinity results in NaN.
Division of an infinity by a finite value results in a signed infinity. The sign is determined by the rule stated above.
Division of a finite value by an infinity results in a signed zero. The sign is determined by the rule stated above.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero. The sign is determined by the rule stated above.
What you should be doing is casting intRate
to a double
instead.
interestRate = (double)intRate / 100 / 12;
Upvotes: 1
Reputation: 79875
You're dividing by zero when you work out monthlyPayment
.
Because you do an integer division when you calculate interestRate
, you finish up with zero. So on the next line, you're actually doing Math.pow(1, -loanLength * 12)
which will always give you 1. You're subtracting the result from 1 and dividing by it. Hence division by zero.
You need that intRate
parameter to be a double
, not an int
, so that you don't get integer division when you calculate interestRate
.
You COULD do this with a cast (as per the other two answers that are currently here), but I think you'd be better off having it as a double
from the beginning - when you first declare intRate
in main
, when you fetch it from the scanner, and also when you pass it to monthlyPayment
.
Upvotes: 1