Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 1

Review Exercises

R5.1 - if quarters > 0 then System.out.println(quarters + " quarters");

Missing parentheses (quarters > 0 ) and illegal keyword then - if (1 + x > Math.pow(x, Math.sqrt(2)) y = y + x;

Unbalanced parentheses around condition, use: if (1 + x > Math.pow(x, Math.sqrt(2))) y = y + x; - if (x = 1) y++; else if (x = 2) y = y + 2;

(x = 1) and (x = 2) are assignments, not comparisons, use (x == 1) and (x == 2) instead. - if (x && y == 0) { x =1; y =1; } Incompatible variable types: If x, y are integers, logical operations like && can not be performed on them. If x, y are boolean, they can't be compared to 0. Use the following instead: if (x == 0 && y == 0) . . .; -if (1 <= x <= 10) System.out.println(x); Invalid condition, use if(1 <= x && x <= 10) instead. - if (s != "nickels" || s != "pennies" || s != "dimes" || s != "quarters") System.out.print("Input error !"); There is no way for the condition to evaluate true. s cannot simultaneously be nickels, pennies, dimes or quarters. If s must be one of the choices, use the following instead: if (s != "nickels" && s != "pennies" && s != "dimes" && s != "quarters") System.out.print("Input error !"); - if (input.equalsIgnoreCase("N") || "NO") return; Invalid compund condition, use the following instead: if (input.equalsIgnoreCase("N") || input.equalsIgnoreCase("NO")) . . . - int x = Integer.parseInt(input); if (x != null) y = y + x; The integer value x can never be null. Use if (input != null) y = y + Integer.parseInt(input); - language = "English" if (country.equals("USA")) if (state.equals("PR")) language = "Spanish"; else if (country.equals("China")) language = "Chinese"; Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 2

The indentation levels give the wrong impression: the else actually pairs with the closest if. Use parentheses: language = "English" if (country.equals("USA")) { if (state.equals("PR")) language = "Spanish"; } else if (country.equals("China")) language = "Chinese";

R5.3 In Java if/else if /else statements are used to express a multiple alternative, in which exactly one from a mutually exclusive set of choices is selected to be executed. Nested if statements are used to express a selection from multiple alternatives when there are multiple conditions for each selection.

/* value of integer choice used to select one of four possible values for x */ if (choice == 1) x = n; else if (choice == 2) x = n * n; else if (choice == 3) x = n * n * n; else x = -2;

/* value of integer choice and value of boolean available used to select one of four possible values for x */ if (choice == 1) { if (x > 0) x = n; else x = n * n; } else { if (x > 0) x = n * n * n; else x = -2; } R5.5 First Second Dick Tom Tom Tomato Churchill church car manufacturer carburetor Harry hairy C++ car Tom Tom Car Carl bar car

R5.7 Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 3

There is no level at which a tax payer ends up with less money if they have a higher income. The income tax is progressive in that higher incomes are taxed at higher rate, but that higher tax rate is applied only to the amount earned above the maiximum level that can be taxed at each preceding lower rate. For example, if you earn $21,460, the first $21,450 are taxed at the lower level of 15%, then the remaining $10 are taxed at the higher 28% rate. If a married couple files jointly and together earn between $35,800 and $42,900, or between $86,500 and $103,800, they will have to pay a higher tax than if they'd filed separately if they are earning the same amount.

R5.9 In the first block, the conditions are evaluated sequentially, so s could be incremented twice. In the second block, the conditional statements are mutually exclusive, so, s cannot be incremented more than once.

R5.11 status = "GOOD"; if (GPA >= 1.5) if (GPA < 2.0) status = "PROBATION"; else status = "FAILING"; Should be: status = "GOOD"; if (GPA >= 1.5) { if (GPA < 2.0) status = "PROBATION"; } else status = "FAILING"; or better: if (GPA >= 2.0) status = "GOOD"; else if (GPA >= 1.5) status = "PROBATION"; else status = "FAILING"; }

R5.13 r == s tests whether r and s are references to the identical Rectangle object. r.equals(s) tests whether r and s are rectangles with the same coordinates. Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 4

R5.15 For the lexicographic comparison, upper- and lowercase are distinguished. Also, "filler characters" such as . - and space are used in the comparison, whereas they would be ignored in the phonebook Lexicographic ordering is like a dictionary alphabetic ordering, but some of the characters have different values which results in their being sorted into a different position. Specifically, all white space (space, horizontal tab, vertical tab, carriage return and line feed) precede digits (0-9) which precede uppercase letters (A-Z) which precede lowercase letters(a-z). The sort order of punctuation and other printing characters is less intuitive. R5.17 To test if an integer equals ten use: int n ; if(n == 10) . . . To test if a floating point number equals ten use: double denom = Math.abs(x); if(Math.abs(y) < 10) denom = 10; if((Math.abs(x - 10) / denom) <= EPSILON ) . . .

R5.19 Marital Income Tax Status S -1 none S 0 none S 21000 3150.00 (21450).15 + (25000-21450).28 = 3217.00 + 994.00 S 25000 = 4211.00 (21450).15 + (51900 - 21450).28 + (60000- S 60000 51900).31 = 3217.00 + 994.00 + 2511.00 = 6722.00 M -1 none M 0 none M 35000 5250.00 (35800).15 + (57000-35800).28 = 5370.00 + M 57000 5936.00 = 11306.00 (35800).15 + (86500 - 35800).28 + (90000- M 90000 86500).31 = 5370.00 + 14196.00 + 1085.00 = 20651.00

Programming Exercises Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 5

P5.1

QuadraticEquation.java public class QuadraticEquation { /** Constructs a quadratic equation and get 2 solutions @param coefficientA coefficient a of quadratic equation @param coefficientB coefficient b of quadratic equation @param coefficientC coefficient c of quadratic equation */ public QuadraticEquation(double coefficientA, double coefficientB, double coefficientC) { a = coefficientA; b = coefficientB; c = coefficientC; discriminant = b * b - 4 * a * c;

}

/** Returns the first solution to the quadratic equation @return the first solution */ public double getSolution1() { return (-b + Math.sqrt(discriminant)) / (2 * a); }

/** Returns the second solution to the quadratic equation @return the second solution */ public double getSolution2() { return (-b - Math.sqrt(discriminant)) / (2 * a); }

/** Determines if there is a solution or not @return true if there is a solution */ public boolean hasSolutions() { return (discriminant > 0); }

double a; double b; double c; double discriminant; } Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 6

QuadraticEquationTest.java

/** This program tests the QuadraticEquation class. */ import javax.swing.JOptionPane; public class QuadraticEquationTest { public static void main(String[] args) { String input = JOptionPane.showInputDialog( "Please enter coefficient a:"); int a = Integer.parseInt(input);

input = JOptionPane.showInputDialog( "Please enter coefficient b:"); int b = Integer.parseInt(input);

input = JOptionPane.showInputDialog( "Please enter coefficient c:"); int c = Integer.parseInt(input);

QuadraticEquation myEquation = new QuadraticEquation(a, b, c);

if(myEquation.hasSolutions()) { System.out.println(myEquation.getSolution1()); System.out.println(myEquation.getSolution2()); } else System.out.println("There are no solutions.");

System.exit(0); } }

P5.3 LabeledPoint.java import java.awt.Graphics2D; import java.awt.geom.Ellipse2D;

/** A point with a label showing the point's coordinates. */ public class LabeledPoint { /** Construct a labeled point. @param anX the x-coordinate @param aY the y-coordinate */ public LabeledPoint(double anX,double aY) Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 7

{ x = anX; y = aY; }

/** Draws the point as a small circle with a coordinate label. @param g2 the graphics context */ public void draw(Graphics2D g2) { //draw a small circle centered around (x, y)

Ellipse2D.Double circle = new Ellipse2D.Double( x - SMALL_CIRCLE_RADIUS, y - SMALL_CIRCLE_RADIUS, 2 * SMALL_CIRCLE_RADIUS, 2 * SMALL_CIRCLE_RADIUS);

g2.draw(circle);

//draw the label

String label ="("+ x + "," + y + ")";

g2.drawString(label, (float)x, (float)y); }

private static final double SMALL_CIRCLE_RADIUS = 2;

private double x; private double y; }

IntersectionApplet.java import java.applet.Applet; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import javax.swing.JOptionPane;

/** An applet that computes and draws the intersection points of a circle and a line. */ public class IntersectionApplet extends Applet { public IntersectionApplet() { String input = JOptionPane.showInputDialog("x:"); x = Integer.parseInt(input); } Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 8

/** Method to draw the circle and compute the intersection points */ public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g;

//draw the circle

Ellipse2D.Double circle = new Ellipse2D.Double(0, 0, 2 * RADIUS, 2 * RADIUS); g2.draw(circle);

//draw the vertical line

Line2D.Double line = new Line2D.Double(x, 0, x, 2 * RADIUS); g2.draw(line);

//compute the intersection points

double a = RADIUS; double b = RADIUS;

double discriminant = RADIUS * RADIUS - (x - a) * (x - a);

if (discriminant < 0) { System.out.println("Error: No Intersection"); }

double root = Math.sqrt(discriminant);

double y1 = b + root; double y2 = b - root;

//draw the intersection points

LabeledPoint p1 = new LabeledPoint(x, y1); LabeledPoint p2 = new LabeledPoint(x, y2);

p1.draw(g2); p2.draw(g2); }

private static final double RADIUS = 100; private static final double DIAMETER = RADIUS * 2;

private double x; } P5.5 Circle.java import java.awt.Graphics2D; import java.awt.geom.Point2D; import java.awt.geom.Ellipse2D; Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 9

/** This class implements a circle and a boolean function to test if a user-given point is inside this circle */ public class Circle { /** Constructs a circle and a point @param x the x-coordinate @param y the y-coordinate */ public Circle(double x, double y) { xLeft = x; yTop = y; }

/** Draws a circle and a point @param g2 the graphics content */ public void draw(Graphics2D g2) { // draw the circle with center (110, 120)

final double CENTERX = 110; final double CENTERY = 120;

Ellipse2D.Double circle = new Ellipse2D.Double(CENTERX - RADIUS , CENTERY - RADIUS, 2 * RADIUS, 2 * RADIUS); g2.draw(circle);

// draw the point

Ellipse2D.Double point = new Ellipse2D.Double(xLeft - 1, yTop - 1, 3, 3); g2.draw(point); }

/** Determine if point is inside or outside the circle @param p the point to test if it is inside the circle @return true if the point is inside the circle */ public boolean isInside(Point2D.Double p) { double dx = xLeft - RADIUS; double dy = yTop - RADIUS;

return ((dx * dx + dy * dy) <= (RADIUS * RADIUS)); }

private static final double RADIUS = 100;

private double xLeft; Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 10

private double yTop; }

ExP5_5.java import java.applet.Applet; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Point2D; import java.awt.geom.Ellipse2D; import javax.swing.JOptionPane;

/** This class tests class Circle to determine if a point is inside a circle with center(110, 120) */ public class ExP5_5 extends Applet { public void init() { String input = JOptionPane.showInputDialog("x:"); x = Integer.parseInt(input);

input = JOptionPane.showInputDialog("y:"); y = Integer.parseInt(input); }

public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g;

Circle circle = new Circle(x, y); circle.draw(g2);

String message; Point2D.Double point = new Point2D.Double(x, y);

if(circle.isInside(point)) message = "Congratulations"; else message = "You missed.";

JOptionPane.showMessageDialog(null, message); }

private double x; private double y; } P5.7 InputChecker.java

/** This class checks if the user wants to continue Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 11

*/ public class InputChecker { /** Constructs an input checker to determine if user wants to continue @param anInput the input of the user */ public InputChecker(String anInput) { input = anInput; result = 0; }

/** Checks the user's input @result the result of checking the input */ public int checkInput() { if (input.equalsIgnoreCase("Y") || input.equalsIgnoreCase("Yes") || input.equalsIgnoreCase("Sure") || input.equalsIgnoreCase("Why not?") || input.equalsIgnoreCase("OK")) result = 1;

else if (input.equalsIgnoreCase("N") || input.equalsIgnoreCase("No")) result = -1;

return result; }

/** Test if the user wants to continue @return true the user wants to continue */ public boolean isYes() { return (checkInput() > 0); }

/** Test if the user does not want to continue @return true the user does not want to continue */ public boolean isNo() { return (checkInput() < 0); }

private String input; private int result; } Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 12

ExP5_7.java import javax.swing.JOptionPane;

/** This tests the InputChecker class */ public class ExP5_7 { public static void main(String[] args) { String input = JOptionPane.showInputDialog( "Do you want to continue?");

InputChecker c = new InputChecker(input);

if(c.isYes()) System.out.println("OK"); else if (c.isNo()) System.out.println("Terminating"); else System.out.println("Bad Input");

System.exit(0); } }

P5.9 Grade.java

/** This class finds the letter representation of a numeric grade */ public class Grade { /** Constructs a letter grade @param numericGrade the numeric grade given by user */ public Grade(double numericGrade) { input = numericGrade; }

/** Find the letter grade from a numeric grade @return grade the letter grade */ public String getLetterGrade() { String letter = ""; String mod= "";

if (input >= 0 && input <= 4.5) Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 13

{ if (input >= 3.5 ) letter = "A"; else if (input >= 2.5 ) letter = "B"; else if (input >= 1.5 ) letter = "C"; else if (input >= 0.5 ) letter = "D"; else letter = "F"; } else letter = "That is not valid";

double remainder = input - (int)input;

if ((0.5 <= remainder) && (remainder < 0.85)) mod = "-"; else if ((0.15 <= remainder) && (remainder < 0.5)) mod = "+";

return letter + mod; }

private double input; }

ExP5_9.java import javax.swing.JOptionPane;

/** This class tests the class Grade to find a letter representation of a numeric grade */ public class ExP5_9 { public static void main(String[] args) { String input = JOptionPane.showInputDialog( "Enter a numeric grade:"); double numGrade = Double.parseDouble(input);

Grade g = new Grade(numGrade);

System.out.println(g.getLetterGrade());

System.exit(0); } } P5.11 TaxReturn.java

/** Class TaxReturn is used to determine the tax amount for a person Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 14

*/ public class TaxReturn { /** Constructs an object TaxReturn @param anIncome of a person @param aStatus of a person...i.e. single or married */

public TaxReturn(double anIncome, String aStatus) { income = anIncome; status = aStatus; }

/** Method used to determine the status of a person and calculate the tax @return the tax amount */ public double getTax() { double tax = 0;

final double RATE1 = 0.15; final double RATE2 = 0.28; final double RATE3 = 0.31;

final double SINGLE_CUTOFF1 = 21450; final double SINGLE_CUTOFF2 = 51900;

final double SINGLE_BASE2 = 3217.50; final double SINGLE_BASE3 = 11743.50;

final double MARRIED_CUTOFF1 = 35800; final double MARRIED_CUTOFF2 = 86500;

final double MARRIED_BASE2 = 5370; final double MARRIED_BASE3 = 19566;

double cutoff1; double cutoff2;

if (status.equalsIgnoreCase("S")) { cutoff1 = SINGLE_CUTOFF1; cutoff2 = SINGLE_CUTOFF2; } else /* status is M */ { cutoff1 = MARRIED_CUTOFF1; cutoff2 = MARRIED_CUTOFF2; }

if (income < cutoff1) tax = RATE1 * income; else if (income < cutoff2) Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 15

tax = RATE1 * cutoff1 + (income - cutoff1) * RATE2; else tax = RATE1 * cutoff1 + RATE2 * (cutoff2 - cutoff1) + RATE3 * (income - cutoff2);

return tax; }

private double income; private String status; }

ExP5_11.java import javax.swing.JOptionPane;

/** This is test class for TaxReturn class */ public class ExP5_11 { public static void main(String[] args) { String input = JOptionPane.showInputDialog( "Please enter your income:"); double income = Double.parseDouble(input);

String status = JOptionPane.showInputDialog( "Please enter S for single, M for married:");

TaxReturn aTaxReturn = new TaxReturn(income, status);

System.out.println("The tax is " + aTaxReturn.getTax());

System.exit(0); } } 5.13 Month.java

/** This class determines the number of days in a month */ public class Month { /** Creates a Month object to determine the number of days in a month @param aMonth is the month in numeric format to determine the number of days */ public Month(int aMonth) { month = aMonth; } Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 16

/** Method to get the number of days in the month @return the days in the tested month */ public int getDays() { int days;

if (month == 4 || month == 6 || month == 9 || month == 11) days = 30; else if (month == 2) days = 28; else if (1 <= month && month <= 12) days = 31; else days = -1;

return days; }

private int month; }

ExP5_13.java import javax.swing.JOptionPane;

/** This is a test driver class for Month class */ public class ExP5_13 { public static void main(String[] args) { String input = JOptionPane.showInputDialog( "Please enter the number of a month:"); int month = Integer.parseInt(input);

Month m = new Month(month);

int days = m.getDays();

if (days < 0) System.out.println("ERROR: Bad Input"); else System.out.println(days + " days");

System.exit(0); } }

P5.15 BankAccount.java

/** A bank account has a balance that can be changed by Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 17

deposits and withdrawals. */ public class BankAccount { /** Constructs a bank account with a zero balance. */ public BankAccount() { balance = 0; }

/** Constructs a bank account with a given balance. @param initialBalance the initial balance */ public BankAccount(double initialBalance) { if (initialBalance >= 0) balance = initialBalance; }

/** Deposits money into the bank account. @param amount the amount to deposit */ public void deposit(double amount) { if (amount >= 0) { double newBalance = balance + amount; balance = newBalance; } }

/** Withdraws money from the bank account. @param amount the amount to withdraw */ public void withdraw(double amount) { if (amount <= balance) { double newBalance = balance - amount; balance = newBalance; } }

/** Gets the current balance of the bank account. @return the current balance */ public double getBalance() { return balance; } Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 18

private double balance; }

ExP5_15.java import javax.swing.JOptionPane;

/** This is a test driver class for BankAccount class */ public class ExP5_15 { public static void main(String[] args) { String input = JOptionPane.showInputDialog( "Enter deposit:"); double dep = Double.parseDouble(input);

input = JOptionPane.showInputDialog( "Enter withdrawal:"); double wit = Double.parseDouble(input);

BankAccount account = new BankAccount(); account.deposit(dep); account.withdraw(wit);

System.out.println("Balance is $" + account.getBalance());

System.exit(0); } }

P5.17 UnitConverter.java

/** This class implements a unit converter for converting from one unit to another */ public class UnitConverter { /** Constructs a unit converter to converter from one unit to another @param unit the unit to convert either from or to */ public UnitConverter(String unit) { final double FLUID_OUNCE_TO_LITER = 29586; final double GALLON_TO_LITER = 3.758; final double OUNCE_TO_GRAM = 28.3495; final double POUND_TO_GRAM = 453.6; final double INCH_TO_METER = 0.0254; final double FOOT_TO_METER = 0.305; final double MILE_TO_METER = 1609; Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 19

if (unit.equals("fl.oz")) factor = FLUID_OUNCE_TO_LITER;

else if (unit.equals("ml")) factor = 0.001;

else if (unit.equals("l")) factor = 1;

else if (unit.equals("oz")) factor = OUNCE_TO_GRAM;

else if (unit.equals("lb")) factor = POUND_TO_GRAM;

else if (unit.equals("mg")) factor = 0.001;

else if (unit.equals("g")) factor = 1;

else if (unit.equals("kg")) factor = 1000;

else if (unit.equals("in")) factor = INCH_TO_METER;

else if (unit.equals("ft")) factor = FOOT_TO_METER;

else if (unit.equals("mi")) factor = MILE_TO_METER;

else if (unit.equals("mm")) factor = 0.001;

else if (unit.equals("cm")) factor = 0.01;

else if (unit.equals("m")) factor = 1;

else if (unit.equals("km")) factor = 1000; else factor = -1;

}

/** Converts a measurement to metric @param measurement the measurement to convert to metric @return metric measurement */ public double toMetric(double measurement) { Solutions Manual: Chapter 5 Big Java, by Cay Horstmann 20

return measurement * factor; }

/** Converts a measurement from metric @param measurement the measurement to convert from metric @return measurement that is converted */ public double fromMetric(double measurement) { return measurement / factor; }

private String type; private double factor; }

ExP5_17.java import javax.swing.JOptionPane;

/** This is a test driver for the UnitConverter class */ public class ExP5_17 { public static void main(String[] args) { String fromUnit = JOptionPane.showInputDialog( "Convert from:");

String toUnit = JOptionPane.showInputDialog( "Convert to:");

UnitConverter from = new UnitConverter(fromUnit); UnitConverter to = new UnitConverter(toUnit);

String input = JOptionPane.showInputDialog( "Value:"); double value = Double.parseDouble(input);

double metric = from.toMetric(value); double converted = to.fromMetric(metric);

if(converted < 0) System.out.println("ERROR: Bad Input"); else System.out.println(value + " " + fromUnit + " = " + converted + " " + toUnit);

System.exit(0); } }