## Programming Exercises

For Chapter 9

THIS PAGE CONTAINS programming exercises based on material from Chapter 9 of this on-line Java textbook. Each exercise has a link to a discussion of one possible solution of that exercise.

Exercise 9.1:Write a program that uses the following subroutine, from Section 3, to solve equations specified by the user.static double root(double A, double B, double C) throws IllegalArgumentException { // Returns the larger of the two roots of // the quadratic equation A*x*x + B*x + C = 0. // (Throws an exception if A == 0 or B*B-4*A*C < 0.) if (A == 0) { throw new IllegalArgumentException("A can't be zero."); } else { double disc = B*B - 4*A*C; if (disc < 0) throw new IllegalArgumentException("Discriminant < zero."); return (-B + Math.sqrt(disc)) / (2*A); } }Your program should allow the user to specify values for

A,B, andC. It should call the subroutine to compute a solution of the equation. If no error occurs, it should print the root. However, if an error occurs, your program should catch that error and print an error message. After processing one equation, the program should ask whether the user wants to enter another equation. The program should continue until the user answers no.

Exercise 9.2:As discussed in Section 1, values of typeintare limited to 32 bits. Integers that are too large to be represented in 32 bits cannot be stored in anintvariable. Java has a standard class,java.math.BigInteger, that addresses this problem. An object of typeBigIntegeris an integer that can be arbitrarily large. (The maximum size is limited only by the amount of memory on your computer.) SinceBigIntegersare objects, they must be manipulated using instance methods from theBigIntegerclass. For example, you can't add twoBigIntegerswith the+operator. Instead, ifNandMare variables that refer toBigIntegers, you can compute the sum ofNandMwith the function callN.add(M). The value returned by this function is a newBigIntegerobject that is equal to the sum ofNandM.The

BigIntegerclass has a constructornew BigInteger(str), wherestris a string. The string must represent an integer, such as "3" or "39849823783783283733". If the string does not represent a legal integer, then the constructor throws aNumberFormatException.There are many instance methods in the

BigIntegerclass. Here are a few that you will find useful for this exercise. Assume thatNandMare variables of typeBigInteger.

N.add(M)-- a function that returns aBigIntegerrepresenting the sum ofNandM.

N.multiply(M)-- a function that returns aBigIntegerrepresenting the result of multiplyingNtimesM.

N.divide(M)-- a function that returns aBigIntegerrepresenting the result of dividingNbyM.

N.signum()-- a function that returns an ordinaryint. The returned value represents the sign of the integerN. The returned value is 1 ifNis greater than zero. It is -1 ifNis less than zero. And it is 0 ifNis zero.

N.equals(M)-- a function that returns abooleanvalue that istrueifNandMhave the same integer value.

N.toString()-- a function that returns aStringrepresenting the value ofN.

N.testBit(k)-- a function that returns abooleanvalue. The parameterkis an integer. The return value istrueif thek-th bit inNis 1, and it isfalseif thek-th bit is 0. Bits are numbered from right to left, starting with 0. Testing "if (N.testBit(0))" is an easy way to check whetherNis even or odd.N.testBit(0)istrueif and only ifNis an odd number.For this exercise, you should write a program that prints

3N+1sequences with starting values specified by the user. In this version of the program, you should useBigIntegersto represent the terms in the sequence. You can read the user's input into aStringwith theTextIO.getln()function. Use the input value to create theBigIntegerobject that represents the starting point of the3N+1sequence. Don't forget to catch and handle theNumberFormatExceptionthat will occur if the user's input is not a legal integer! You should also check that the input number is greater than zero.If the user's input is legal, print out the

3N+1sequence. Count the number of terms in the sequence, and print the count at the end of the sequence. Exit the program when the user inputs an empty line.

Exercise 9.3:A Roman numeral represents an integer using letters. Examples are XVII to represent 17, MCMLIII for 1953, and MMMCCCIII for 3303. By contrast, ordinary numbers such as 17 or 1953 are called Arabic numerals. The following table shows the Arabic equivalent of all the single-letter Roman numerals:M 1000 X 10 D 500 V 5 C 100 I 1 L 50When letters are strung together, the values of the letters are just added up, with the following exception. When a letter of smaller value is followed by a letter of larger value, the smaller value is subtracted from the larger value. For example, IV represents 5 - 1, or 4. And MCMXCV is interpreted as M + CM + XC + V, or 1000 + (1000 - 100) + (100 - 10) + 5, which is 1995. In standard Roman numerals, no more than thee consecutive copies of the same letter are used. Following these rules, every number between 1 and 3999 can be represented as a Roman numeral made up of the following one- and two-letter combinations:

M 1000 X 10 CM 900 IX 9 D 500 V 5 CD 400 IV 4 C 100 I 1 XC 90 L 50 XL 40Write a class to represent Roman numerals. The class should have two constructors. One constructs a Roman numeral from a string such as "XVII" or "MCMXCV". It should throw a

NumberFormatExceptionif the string is not a legal Roman numeral. The other constructor constructs a Roman numeral from anint. It should throw aNumberFormatExceptionif theintis outside the range 1 to 3999.In addition, the class should have two instance methods. The method

toString()returns the string that represents the Roman numeral. The methodtoInt()returns the value of the Roman numeral as anint.At some point in your class, you will have to convert an

intinto the string that represents the corresponding Roman numeral. One way to approach this is to gradually "move" value from the Arabic numeral to the Roman numeral. Here is the beginning of a routine that will do this, wherenumberis theintthat is to be converted:String roman = ""; int N = number; while (N >= 1000) { // Move 1000 from N to roman. roman += "M"; N -= 1000; } while (N >= 900) { // Move 900 from N to roman. roman += "CM"; N -= 900; } . . // Continue with other values from the above table. .(You can save yourself a lot of typing in this routine if you use arrays in a clever way to represent the data in the above table.)

Once you've written your class, use it in a main program that will read both Arabic numerals and Roman numerals entered by the user. If the user enters an Arabic numeral, print the corresponding Roman numeral. If the user enters a Roman numeral, print the corresponding Arabic numeral. (You can tell the difference by using

TextIO.peek()to peek at the first character in the user's input. If that character is a digit, then the user's input is an Arabic numeral. Otherwise, it's a Roman numeral.) The program should end when the user inputs an empty line. Here is an applet that simulates my solution to this problem:

Exercise 9.4:The file Expr.java defines a class,Expr, that can be used to represent mathematical expressions involving the variablex. The expression can use the operators +, -, *, /, and ^, where ^ represents the operation of raising a number to a power. It can use mathematical functions such assin,cos,abs, andln. See the source code file for full details. TheExprclass uses some advanced techniques which have not yet been covered in this textbook. However, the interface is easy to understand. It contains only a constructor and two public methods.The constructor

new Expr(def)creates anExprobject defined by a given expression. The parameter,def, is a string that contains the definition. For example,new Expr("x^2")ornew Expr("sin(x)+3*x"). If the parameter in the constructor call does not represent a legal expression, then the constructor throws anIllegalArgumentException. The message in the exception describes the error.If

funcis a variable of typeExprandnumis of typedouble, thenfunc.value(num)is a function that returns the value of the expression when the numbernumis substituted for the variablexin the expression. For example, ifExprrepresents the expression3*x+1, thenfunc.value(5)is3*5+1, or 16. If the expression is undefined for the specified value ofx, then the special valueDouble.NaNis returned.Finally,

func.getDefinition()returns the definition of the expression. This is just the string that was used in the constructor that created the expression object.For this exercise, you should write a program that lets the user enter an expression. If the expression contains an error, print an error message. Otherwise, let the user enter some numerical values for the variable

x. Print the value of the expression for each number that the user enters. However, if the expression is undefined for the specified value ofx, print a message to that effect. You can use theboolean-valued functionDouble.isNaN(val)to check whether a number,val, isDouble.NaN.The user should be able to enter as many values of

xas desired. After that, the user should be able to enter a new expression. Here is an applet that simulates my solution to this exercise, so that you can see how it works:

Exercise 9.5:This exercises uses the classExpr, which was described in Exercise 9.4. For this exercise, you should write an applet that can graph a function,f(x), whose definition is entered by the user. The applet should have a text-input box where the user can enter an expression involving the variablex, such asx^2orsin(x-3)/x. This expression is the definition of the function. When the user presses return in the text input box, the applet should use the contents of the text input box to construct an object of typeExpr. If an error is found in the definition, then the applet should display an error message. Otherwise, it should display a graph of the function. (Note: ATextFieldgenerates anActionEventwhen the user presses return.)The applet will need a canvas for displaying the graph. To keep things simple, the canvas should represent a fixed region in the xy-plane, defined by

-5 <= x <= 5and-5 <= y <= 5. To draw the graph, compute a large number of points and connect them with line segments. (This method does not handle discontinuous functions properly; doing so is very hard, so you shouldn't try to do it for this exercise.) My applet divides the interval-5 <= x <= 5into 300 subintervals and uses the 301 endpoints of these subintervals for drawing the graph. Note that the function might be undefined at one of thesex-values. In that case, you have to skip that point.A point on the graph has the form

(x,y)whereyis obtained by evaluating the user's expression at the given value ofx. You will have to convert these real numbers to the integer coordinates of the corresponding pixel on the canvas. The formulas for the conversion are:a = (int)( (x + 5)/10 * width ); b = (int)( (5 - y)/10 * height );where

aandbare the horizontal and vertical coordinates of the pixel, andwidthandheightare the width and height of the canvas.Here is my solution to this exercise:

[ Chapter Index | Main Index ]