user3175451
user3175451

Reputation: 163

Java always wants to round when i am doing math

The problem is happening, I THINK, where the program uses the interest rate. Using the test data: Loan amount: $500,000.00 Yearly interest rate: 5.6% Number of years: 30

I should get the result: Monthly payment: $2,870.39

Instead, I get: Loan amount: $500,000.00 Yearly interest rate: 6% Number of years: 30.0 Monthly Payment: $34,783.54

Help please

EDIT- This is for a homework assignment, and the professor has noted that he does not want us using BigDecimal objects. Why is beyond me, as I have demonstrated my ability to solve this using BigDecimal math in the past.

Here is the code:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package workbook5.pkg2;
import java.util.Scanner;
import java.text.*;
/**
 *
 * @author Daniel
 */
public class Workbook52 {

    /**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    Scanner sc = new Scanner(System.in);
    double loanAmount = getDouble(sc, "Enter loan amount: ", 0, 1000000);
    double interestRate = getDouble(sc, "Enter interest rate (5% as .05): ", 0, 20);
    double years = getInt(sc, "Enter amount of years: ", 0, 100);
    double payment = calculatePayment(loanAmount, interestRate, years);
    System.out.println("FORMATTED RESULTS");
    System.out.println("Loan amount:          " + NumberFormat.getCurrencyInstance().format(loanAmount));
    System.out.println("Yearly interest rate: " + NumberFormat.getPercentInstance().format(interestRate));
    System.out.println("Number of years:      " + years);
    System.out.println("Monthly Payment:      " + NumberFormat.getCurrencyInstance().format(payment));
}
public static double getDouble(Scanner sc, String prompt, double min, double max){
    double i = 0;
    boolean isValid = false;
    while (isValid == false)
    {    
        System.out.println(prompt);
        if (sc.hasNextDouble())
        {
          i = sc.nextDouble();
          isValid=true;
        }


        else
        {
            System.out.println("Error! Invalid double value. Try again.");

        }
        sc.nextLine();
        if (isValid == true && i <= min)
        {
            System.out.println("Error: Number must be greater than " + min);
            isValid = false;
        }
        else if (isValid == true && i >= max)
        {
            System.out.println("Error: Number must be less than " + max);
            isValid = false;
        }
    }
    return i;
}

public static int getInt(Scanner sc, String prompt, int min, int max){
    int i = 0;
    boolean isValid = false;
    while (isValid == false)
    {
        System.out.println(prompt);
        if (sc.hasNextInt())
        {
          i = sc.nextInt();
          isValid=true;
        }        
        else
        {
            System.out.println("Error! Invalid integer value. Try again.");

        }
        sc.nextLine();
        if (isValid == true && i <= min)
        {
            System.out.println("Error: Number must be greater than " + min);
            isValid = false;
        }
        else if (isValid == true && i >= max)
        {
            System.out.println("Error: Number must be less than " + max);
            isValid = false;
        }
    }    

    return i;
    }






 public static double calculatePayment(double amount, double interest, double years) {
       double monthlyPayment = amount * interest/(1 - 1/Math.pow(1 + interest, years));
       return monthlyPayment;
   }
}

Upvotes: 1

Views: 136

Answers (3)

Bill the Lizard
Bill the Lizard

Reputation: 405815

There's nothing wrong with rounding in your program. The inputs to your formula are wrong. You're using the annual interest rate and number of years to calculate a monthly payment. You need to convert to a monthly rate and number of terms. Try this:

public static double calculatePayment(double amount, double interest, double years) {
    double monthlyInterest = interest / 12.0;
    double terms = years * 12.0;
    double monthlyPayment = amount * monthlyInterest
            / (1 - 1 / Math.pow(1 + monthlyInterest, terms));
    return monthlyPayment;
}

Upvotes: 0

Bohemian
Bohemian

Reputation: 425083

If you store and calculate all money values in cents, you can safely use int (or long for very large amounts).

The banking industry (EFTPOS especially) uses cents, and if it's good enough for them it should be OK for you too.

You only render the number as a decimal number of dollars with currency symbol.

Upvotes: 1

aryann
aryann

Reputation: 949

Whenever you are dealing with money in java, the data type that you use is BigDecimal and not float or double. Modify your program to use BigDecimal instead of double and you should get correct and expected results.

Upvotes: 1

Related Questions