Calculating discount factor in java - java

I am trying to calculate monthly loan payments the formula Loan Payment = Amount / Discount Factor on www.thebalance.com
According to the website discount factor is calculated with this formula (D) = {[(1 + i) ^n] - 1} / [i(1 + i)^n] I tried interpreting this into Java and came up with
double discountFactor = (Math.pow((1 + interest), numberOfPayments) - 1) / Math.pow(interest * (1 + interest), numberOfPayments);
But it outputs infinityam not so good with Math, can someone help point out the issue?

double discountFactor = (Math.pow((1 + interest), numberOfPayments) - 1) /
(interest * Math.pow((1 + interest), numberOfPayments));
interest is not part of the power, it should be outside power.

put the 'interest' outside the second power function not inside.
double discountFactor = (Math.pow((1 + interest),numberOfPayments)-1)/(interest*Math.pow((1+interest),numberOfPayments));

Related

My Java math expressions using Math.floor() come out to 0 instead of the intended number, even though my paper calculations say it should be otherwise

I'm a beginner programmer and I am writing a change machine program. I almost have it down, but for some reason, Math.floor() give a result of 0 instead of the intended number.
I've tried using Math.round() instead, but I'm fairly sure it should be Math.floor() for most accurate results.
public void calculateChange(){
changeTotal = moneyGiven - total;
wholeDollars = Math.floor(changeTotal);
quarters = Math.floor((changeTotal - wholeDollars)/.25);
dimes = Math.floor(((changeTotal - wholeDollars) - quarters * .25)/.1);
nickles = Math.floor(((changeTotal - wholeDollars) - quarters * .25 - dimes * 0.1)/.05);
pennies = Math.floor(((changeTotal - wholeDollars) - quarters * .25 - dimes * 0.1 - nickles * .05)/ .01);
}
For example, when I run the method below with the input of $5 as cash given, and $1.29 as the transaction total, I get change of 3 dollars, 2 quarters, 2 dimes, 0 nickles, and 0 pennies.
The penny value should be 1. It seems to only have this issue if the result for any given expression should be 1.
First of all, your code does not show any of the data types of your variables. This makes it difficult for me to pinpoint the exact cause of the issue here.
That aside, your variables need to be cast as integers. I've made edits to the structure of your method; moneyGiven and total are now float parameters.
Calling the method as calculateChange(5, 1.29f) gave me the correct output of 3 2 2 0 1.
public static void calculateChange(float moneyGiven, float total) {
float changeTotal = moneyGiven - total;
int wholeDollars = (int) Math.floor(changeTotal);
int quarters = (int) Math.floor((changeTotal - wholeDollars)/.25);
int dimes = (int) Math.floor(((changeTotal - wholeDollars) - quarters * .25)/.1);
int nickles = (int) Math.floor(((changeTotal - wholeDollars) - quarters * .25 - dimes * 0.1)/.05);
int pennies = (int) Math.floor(((changeTotal - wholeDollars) - quarters * .25 - dimes * 0.1 - nickles * .05)/.01);
System.out.println(wholeDollars + " " + quarters + " " + dimes + " " + nickles + " " + pennies);
}
You seem to have declared your variables as floating point numbers and are getting rounding errors as a result.
I'll be taking your example with moneyGiven = 5.00 dollars and total = 1.29 dollars.
While the value of the expression (changeTotal - wholeDollars) is 0.71 and the value of quarters * .25 is 0.5, subtracting them in the expressiong (changeTotal - wholeDollars) - quarters * .25 actually results in 0.20999999999999996 due to the way floating point numbers are represented in memory and math operations.
In the end, the result of the entire expression ((changeTotal - wholeDollars) - quarters * .25 - dimes * 0.1 - nickles * .05)/ .01 is 0.9999999999999953, which then gets floored to 0.
The kind of operations you perform also have an influence. If I change your divisions into multiplications of the inverse like the following, I actually get 1.0000038146972645 as result of the final expression, which is then floored to 1:
public static void calculateChange(double moneyGiven, double total) {
double changeTotal = moneyGiven - total;
double wholeDollars = Math.floor(changeTotal);
double quarters = Math.floor((changeTotal - wholeDollars) * 4.0);
double dimes = Math.floor(((changeTotal - wholeDollars) - quarters / 4.0) * 10);
double nickles = Math.floor(((changeTotal - wholeDollars) - quarters / 4.0 - dimes / 10.0) * 20.0);
double pennies = Math.floor(((changeTotal - wholeDollars) - quarters / 4.0 - dimes / 10.0 - nickles / 20.0) * 100);
System.out.println(wholeDollars + " " + quarters + " " + dimes + " " + nickles + " " + pennies);
}
Even storing the intermediate results as integers does not fully negate the issue, because your total and moneyGiven are still floating point values. By changing their type from double to float, you mitigate the issue somewhat by having less precision, which may result in more favorable rounding. But it does not reliably solve the underlying problem.
Serious financial programs should never use primitive floating point datatypes to do any calculations because of rounding errors. Instead, they use a special type called BigDecimal.
I would re-think the solution a bit here. There's nothing too wrong with your approach, but thinking about this using integer math rather than floating point will simplify the whole operation. You also can use intermediate variables to avoid repeating the same operations over and over again.
int dollars = (int) (changeTotal);
int cents = (int) (changeTotal * 100) % 100;
int quarters = cents / 25;
cents = cents % 25;
int dimes = cents / 10;
cents = cents % 10;
int nickels = cents / 5;
cents = cents % 5;
int pennies = cents;

Calculating Loan Interest and Duration of loan. Java

The following 2 methods are intended to calculate the length of loan(number of monthly payments that have to be paid and the interest due in the loan, respectively, given the parameters in which r is the monthly interest rate(APR), A is the loan amount(principal), P is the monthly payment and N is the number of payments that need to be made. However neither of the methods calculate correctly. How do I fix them so that they provide the number of months the payment must be made and the interest accrued?
public static double loanLength(double r, double A, double P){
double N = (Math.log(1 / (1 - ((r * A) / P)))) / Math.log(1 + r);
return N;
}
public static double loanInterest(double P, double N, double A){
double I = ((P * N) - A);
return I;
}
According to your example input it's just an arithmetic error.
The line double N = (Math.log(1 / (1 - ((r * A) / P)))) / Math.log(1 + r); has some calculations in it. The one that fails (or results in NaN) is Math.log(1 / (1 - ((r * A) / P))).
If we insert the example values: Math.log(1 / (1 - ((0.1 * 10000) / 500))) and we calculate that out:
1. Math.log(1 / (1 - ((0.1 * 10000) / 500)))
2. Math.log(1 / (1 - (1000 / 500)))
3. Math.log(1 / (1 - 2))
4. Math.log(1 / -1)
5. Math.log(-1) // <-- here happens the error
A logarithm of a number smaller/equals than 0 is not defined. So your equation is wrong
This site explains that the interest rate and payment have to be for the same period.
I guess in your case 10% is per year, while 500 is per month. So you need to divide 10 or multiply 500 by 12 to make them fit together. Otherwise, your calculation will give you the duration for a loan with 10%/500payment per month or per year (or any duration really), which can never be payed back: in every period there is 1000 interest, but only 500 payment.
Hence, log(-x) produces NaN, meaning you can never pay back.

display monthly payment in pow(a,b) method

The formula to compute the monthly payment is as follows:
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate)numberOfYears x 12 ))
In the above formula, you have to compute (1 + monthlyInterestRate)numberOfYears x 12 ). The pow(a,b) method in the Java API Math class can be used to compute ab.
so how to put this in pow(a,b) method ?
The javadoc for the java.lang.Math class might help you here. Is there something specific you don't understand about that?
So the code to compute the b power of a should look something like this:
double result = Math.pow(a, b);
The formula you have does not look quite right. From Exact_formula_for_monthly_payment The formula should be
P= (L i)/(1- 1/(1+i)^n )
Where L is the loan amount, i is the monthly interest, and n number of periods. In your formula
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate)numberOfYears x 12 ))
the exponential sign has been missed out. I think you want
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate) ^ (numberOfYears x 12) ))
To calculate this in java you would want
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 – (1 / Math.pow(1 + monthlyInterestRate,numberOfYears * 12)));
Which could be simplified to
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 – Math.pow(1 + monthlyInterestRate,-numberOfYears * 12));
using a negative exponent.

Monthly payment calculator returning wrong payment

I am supposed to make a monthly payment calculator in java with the given formula.
The formula for me to use is
M = P * i/ 1 - (1+i)^-n
where
P is the loan principal (i.e. the amount borrowed)
i is monthly interest rate (annual_interest_rate / 12; expressed as decimal)
N is time (number of monthly payments in total years of loan; i.e. years * 12)
The code below is my attempted function to get the monthly payment.
But if I put in 6 years with a loan amount of 200, I get 140 using the formula.
I am stumped as to why I get that number. Any help would be appreciated
public static int calMonthlyPay(double loanAmt, int y) {
double m = 0.0, interest = 0.0, annualIRate = 0.0;
double months = 0.0;
months = y * 12;
annualIRate = getAnnualIRate(y);
interest = annualIRate / 12;
System.out.println(interest);
System.out.println(months);
System.out.println(loanAmt);
System.out.println(y);
m = (loanAmt * (interest - Math.pow((1 + interest), -months))); // This is my formula calculation
System.out.println(m);
return 0;
}
private static double getAnnualIRate(int y) {
switch (y) {
case 2:
return 5.7;
case 3:
return 6.2;
case 4:
return 6.8;
case 5:
return 7.5;
case 6:
return 8.4;
default:
return 8.4;
}
}
If I understood your formula right, it should be:
m = loanAmt * interest - Math.pow(1 + interest, -months);
What you have now is :
m = (loanAmt * (interest / 1 - Math.pow((1 + interest), -months))) =
(loanAmt * (interest - Math.pow((1 + interest), -months)))
You should use the parentheses correctly :
m = loanAmt * (interest / (1 - Math.pow(1 + interest, -months)));
Your formula is incorrect, it need to be
loanAmt * (interest / (1 - Math.pow (1 + interest, -months)));
And there's a error in interest value formula, it need to be
interest = annualIRate / 100 / 12;
So your method calMonthlyPay(200, 6) gives 3 now, which is correct.

Need help porting this equation to java

I'm trying to make a program that calculates the required score to level in a game and the equation works fine on my calculator but not when i try changing it to work with java.
the equation is 5,000 / 3 * (4n^3 - 3n^2 - n) + 1.25 * 1.8^(n - 60) for example level 49 you should need to have a total score of 772240000 points and the calculator gives this answer but my java program doesn't. here is the code i tried.
for (int i = 0; i <= 100; i++) {
double score = (double) ((5000 / 3) * (Math.pow(4 * i, 3) - Math.pow(3 * i, 2) - i) + (1.25 * Math.pow(1.8, i - 60)));
System.out.println("Level " + i + " requires " + (long) score);
}
This doesnt seem to work right and gives 12513130000 as the required points for lvl 49. If anyone can get it to work would you miind explaining what i did wrong.
You're messing up your Math.pow calls, but you can avoid some of them entirely:
double score = (double) ((5000 / 3) * (4 * i * i * i - 3 * i * i - i) + (1.25 * Math.pow(1.8, i - 60)));
Here's what's wrong: Math.pow(4 * i, 3) is actually (4i)^3 and not 4(i^3). To do the latter, you would need the following:
4 * Math.pow(i, 3)
I'm not entirely sure about the integer division part (you are casting it to double), but you may have to change 5000 / 3 to 5000.0 / 3.
Your problem is inside Math.pow - you're multiplying your index value by a scalar each time.
4 * Math.pow(i, 3)
And
3 * Math.pow(i, 2)
Should fix it.
Edit: And the integer division mentioned in other answers.

Categories

Resources