/** * Matt Kretchmar * March 10, 2006 * LoanCalculator.java * This program computes monthly payments for an automobile loan. * The user specifies the principal (amount borrowed) and the * interest rate. The term is set at 48 months. */ import java.util.Scanner; class LoanCalculator { public static void main ( String args[] ) { double principal; double rate; double payment; principal = getData("principal",10000,20000); rate = getData("interest rate",7.0,10.0); payment = getData("monthly payment",0,1000); double residual = computeResidual(rate,principal,payment,48); System.out.println("Residual = "+ residual); // This part of the program now searches for the optimal monthly payment. // We start with an upper and lower bound, then use a binary search procedure // to reduce the interval in half each time. We repeat until we narrow in on // an upper and lower bound that are 1 cent apart. // Initial lower bound: principal / term // Initial upper bound: principal * rate^term / term double amount; double remaining; int upperBound; int lowerBound; int middle; lowerBound = (int)(principal*100) / 48; upperBound = (int)(principal*100 * Math.pow( 1.0+rate/1200, 48)) / 48; System.out.println("(" + (upperBound/100.0) + ", " + (lowerBound/100.0) + ")"); while ( upperBound - lowerBound > 1) { System.out.print("(" + (upperBound/100.0) + ", " + (lowerBound/100.0) + ")"); middle = ( lowerBound + upperBound ) / 2; amount = middle / 100.0; remaining = computeResidual(rate,principal,amount,48); System.out.println(" middle = " + middle + ", res = " + remaining); if ( remaining > 0 ) lowerBound = (int)(amount * 100); else upperBound = (int)(amount * 100); } System.out.println("(" + (upperBound/100.0) + ", " + (lowerBound/100.0) + ")"); residual = computeResidual(rate,principal,upperBound/100.0,47); residual = Math.round(residual*100) / 100.0; System.out.println("47 payments of " + (upperBound/100.0) + " and 1 payment of " + residual ); } /** * This method prompts the user to enter data between lowest and highest. * The user's input is tested for this range and they are reprompted until * the data entered falls within the range. */ public static double getData ( String msg, double lowest, double highest ) { double p = 0; do { Scanner keyboard = new Scanner(System.in); System.out.println("Enter " + msg + " (" + lowest + " to " + highest + "): "); p = keyboard.nextDouble(); } while ( p < lowest || p > highest ); return p; } /** * This method accepts the rate, principal, payment, and term (number of payments) * as input parameters for an automobile loan. The residual amount of the principal is * computed and returned at the end of the car loan. */ public static double computeResidual ( double rate, double principal, double payment, int numPayments ) { // rate adjusted to montly value rate = rate / 100; rate = rate / 12; for ( int i = 0; i < numPayments; i++ ) { // add interest principal = principal + principal * rate; // subtract payment principal = principal - payment; } return principal; } }