Chapter 4
<< Chapter 3 | HomeworkTrailIndex | Chapter 5 >>
Bits and Bytes
Computers use base 2, not base 10, like most humans. Take a look at Bits And Bytes or The binary game
In base 10, {⚠ $\frac{1}{3} $
} has issues..... 0.33333333333 is only approximately equal to {⚠ $\frac{1}{3} $
} -- to be exact, there shouldn't be an end to those repeating 3's. There is similar trouble in all bases, even base two. Try 4.35*100 for example....shouldn't that be 435.0? Try it.... Use the BlueJ code pad to and experiment-- can you see the trouble? Can you find another?
There are other simple data types in java like the int, but smaller. The byte
type is an integer that only takes 8 bits (1 byte=8 bits). In the BlueJ code pad, try this:
byte x=127; x+1
Isn't 127+1=128? What does your poor computer think it is? This is an overflow of the poor byte
.
{⚠ $2^7-1=127$
} so thats why there is a problem.
The short
is 2 bytes (or 16 bits) so it has trouble adding 1 to 32767 (Since {⚠ $2^{15}-1=32767 $
} ) You can compute this using the Math.pow()
method:
(short)( Math.pow(2,15)-1 )
Use the code pad to try an overflow of a short.
The int
is 4 bytes (or 32 bits). How big a number can fit into an int
? Try to overflow an int
!
Once in a wile, even big companies like Intel can make mistakes. The Pentium processor had a famous blunder.
{⚠ $ \left(\frac{4195835}{3145727}\right) \left(\frac{3145727}{1} \right) - 4195835 = 0 $
}, right? Shouldn't those 3145727's cancel, leaving 4195835-4195835=0? Well, according to a pentium FP, it's 256 not 0! Try it in your BlueJ code pad.... is it fixed now?
Demo Code
Implement a class QuadraticEquation (you can start with the code below if you wish to save time) whose constructor receives the coefficients a, b, c of the quadratic equation ax2 + bx + c = 0. Supply methods getSolution1
and getSolution2
that get the solutions, using the quadratic formula. Write a test class QuadraticEquationTester
(or use the sample one below if you wish) that constructs a QuadraticEquation
object, and prints the two solutions. For example, if you make QuadraticEquation myProblem = new QuadraticEquation(2,5,-3)
, the solutions should be .5
and -3
Recall that if {⚠ $ax^2+bx+c=0$
} then {⚠ $ x= \frac{-b \pm \sqrt{b^2-4ac}}{2a} $
}
QuadraticEquationTester.java
public class QuadraticEquationTester { public static void main(String[] args) { QuadraticEquation myProblem = new QuadraticEquation(2.0,5.0,-3.0); double x1 = myProblem.getSolution1(); double x2 = myProblem.getSolution2(); System.out.println(myProblem); System.out.println("The solutions are "+x1+" and "+x2); System.out.println("Expected .5 and -3"); } }
QuadraticEquation.java
public class QuadraticEquation { private double a,b,c; public QuadraticEquation (double theA, double theB, double theC ) { a=theA; b=theB; c=theC; } public double getSolution1() { return 0;// your work here } public double getSolution2() { return 0;//your work here } public String toString() { return a+"x^2 + "+b+"x + "+c+" =0"; } }
Write a method that gets the last n characters from a string. For example, last("Hello, World!", 5) should return the string "orld!".
public class Strings { /** Gets the last n characters from a string. @param s a string @param n a nonnegative integer <= s.length() @return the string that contains the last n characters of s */ public String last(String s, int n) { // your work here } }
Complete the following function that computes the length of a line segment with end points (x1, y1) and (x2, y2). According to the Pythagorean theorem, the length is {⚠ $\sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}$
}.
Lines.java
public class Lines { /** Computes the length of a line segment @param x1 the x-coordinate of the starting point @param y1 the y-coordinate of the starting point @param x2 the x-coordinate of the ending point @param y2 the y-coordinate of the ending point @return the length of the line segment joining (x1, y1) and (x2, y2) */ public static double segmentLength(double x1, double y1, double x2, double y2) { // your work here } }
LinesTester.java
public class LinesTester { /** * @param args */ public static void main(String[] args) { System.out.print("Expecting 5:"+Lines.segmentLength(0,0,3,4)); } }
Demo: DigitPeeler
- Write a method that returns the last digit of an
int
- Write a method that returns the first digit of an
int
that hasn
digits.
DigitPeeler.java
public class DigitPeeler { /** * DigitPeeler is a class that exists * to make a small "library" of static functions, * just in the same way that Math and Integer classes * serve as a collection of static methods. * * You don't need to create an instance of this class * to use these functions, because they are static */ public static int lastDigit(int n){ } /** * precondition: n has at least 1 digit * @param n the number * @param numberOfDigits of n * @return the first digit of n */ public static int firstDigit(int n, int numberOfDigits){ //Hint: Math.pow(10,3) returns 1000 } }
DigitPeelerTester.java
public class DigitPeelerTester { public static void main(String[] args) { System.out.println("This tests the DigitPeeler methods\n"); System.out.println("Last digit of 56834 is "+DigitPeeler.lastDigit(56834)); System.out.println("Expected 4\n"); System.out.println("First digit of 56834 is "+DigitPeeler.firstDigit(56834, 5)); System.out.println("Expected 5\n"); } }
Day of the Week Algorithm
Try the String puzzles at Javabat
Review Exercises
These are important activities to do, but not really something I can grade. This is like the "Training ground" in a video game where you learn the buttons before you go out on a quest. Skip these, and you may not last very long in the game. For each of these, make a guess, and then type the code, and see if the computer behaved the way you expected. True learning happens when you are surprised by a result, and you figure out what it did what it did!
- R4.1 Write the following mathematical expressions in Java.
⚠ $s=s_0+v_0t+\frac{1}{2}gt^2$
}
⚠ $G=4\pi^2\frac{a^3}{p^2(m_1+m_2)}$
}
⚠ $FV=PV\cdot\left(1+\frac{INT}{100}\right)^{YRS}$
}
⚠ $c=\sqrt{a^2+b^2-2ab\cos \theta}$
}
- R4.2 Write the following Java expressions in mathematical notation.
dm = m * (Math.sqrt(1 + v / c) / (Math.sqrt(1 - v / c) - 1));
volume = Math.PI * r * r * h;
volume = 4 * Math.PI * Math.pow(r, 3) / 3;
p = Math.atan2(z, Math.sqrt(x * x + y * y));
- R4.5 What does Java report
4.35 * 100.0
? Why? - R4.7 Let
n
be an integer andx
a floating-point number. Explain the difference between
n = (int) x;
and n = (int) Math.round(x);
- R4.10
- R4.11 If
x
is anint
ands
is aString
, then which are true?
Integer.parseInt(“” + x)
is the same as x
“” + Integer.parseInt(s)
is the same as s
s.substring(0, s.length())
is the same as s
- R4.13 How do you get the last digit of an integer? The first digit? That is, if
n
is 23456, how do you find out that the first digit is 2 and the last digit is 6?
Do not convert the number to a string. Hint: try % or Math.log
. If you use the Math.log
method, Java uses the natural log, and you want base 10.
double logn = Math.log(n) / Math.log(10); // 10 to what power is 23456? about 4.37025395296 int ndigits = (int) logn; // round to 4. int pow10 = (int) Math.pow(10, ndigits); //four zeros: 10000 int first = n / pow10; // 23456 over 1000 is 2.
Don't worry, we'll see this task later when we have loops and conditional statements, and that process will seem easier.
- R4.16
Programming Exercises
For 8 points choose 2 of these four, for 9 points, choose 3 out of these four, and for 10 points, do all four! (There is no 11 point "Extra Credit" this chapter since Chapter 5 is so much more interesting, I'd rather you move on to the good stuff!)
- P4.11 Giving Change
Enhance the CashRegister
class so that it directs a cashier how to give change. The cash register computes the amount to be returned to the customer, in pennies.
Here is some starter code:
/** A cash register totals up sales and computes change due. */ public class CashRegister { public static final double QUARTER_VALUE = 0.25; public static final double DIME_VALUE = 0.1; public static final double NICKEL_VALUE = 0.05; public static final double PENNY_VALUE = 0.01; private double purchase; private double payment; /** Constructs a cash register with no money in it. */ public CashRegister() { purchase = 0; payment = 0; } /** Records the purchase price of an item. @param amount the price of the purchased item */ public void recordPurchase(double amount) { //your code here } /** Enters the payment received from the customer. @param dollars the number of dollars in the payment @param quarters the number of quarters in the payment @param dimes the number of dimes in the payment @param nickels the number of nickels in the payment @param pennies the number of pennies in the payment */ public void enterPayment(int dollars, int quarters, int dimes, int nickels, int pennies) { //your code here } /** Computes the change due and resets the machine for the next customer. @return the change due to the customer */ public double giveChange() { //your code here } }
Add the following methods to the CashRegister
class:
/** Computes the number of dollars due to the customer. @return the number of dollars in the change due */ public int giveDollars() { int change = (int) (payment - purchase); if (change < 0) return 0; payment = payment - change; return change; } /** Computes the number of quarters due to the customer. @return the number of quarters in the change due */ public int giveQuarters() { int change = (int) ((payment - purchase) / QUARTER_VALUE); payment = payment - change * QUARTER_VALUE; return (int) change; } /** Computes the number of dimes due to the customer. @return the number of dimes in the change due */ public int giveDimes() { int change = (int) ((payment - purchase) / DIME_VALUE); payment = payment - change * DIME_VALUE; return (int) change; } /** Computes the number of nickels due to the customer. @return the number of nickels in the change due */ public int giveNickels() { int change = (int) ((payment - purchase)/NICKEL_VALUE); payment = payment - change * NICKEL_VALUE; return (int) change; } /** Computes the number of pennies due to the customer. @return the number of pennies in the change due */ public int givePennies() { ///your code here return (int) change; }
Each method computes the number of dollar bills or coins to return to the customer, and reduces the change due by the returned amount. You may assume that the methods are called in this order. Here is a test class:
public class CashRegisterTester { public static void main(String[] args) { CashRegister register = new CashRegister(); register.recordPurchase(8.37); register.enterPayment(10, 0, 0, 0, 0); System.out.println("Dollars: " + register.giveDollars()); System.out.println("Expected: 1"); System.out.println("Quarters: " + register.giveQuarters()); System.out.println("Expected: 2"); System.out.println("Dimes: " + register.giveDimes()); System.out.println("Expected: 1"); System.out.println("Nickels: " + register.giveNickels()); System.out.println("Expected: 0"); System.out.println("Pennies: " + register.givePennies()); System.out.println("Expected: 3"); } }
If you prefer, here is a more interactive way to test your code:
import java.util.Scanner; /** This program simulates a transaction in which a user pays for an item and receives change. */ public class CashRegisterSimulator { public static void main(String[] args) { Scanner in = new Scanner(System.in); CashRegister register = new CashRegister(); System.out.print("Enter price: "); double price = in.nextDouble(); register.recordPurchase(price); System.out.print("Enter dollars: "); int dollars = in.nextInt(); System.out.print("Enter quarters: "); int quarters = in.nextInt(); System.out.print("Enter dimes: "); int dimes = in.nextInt(); System.out.print("Enter nickels: "); int nickels = in.nextInt(); System.out.print("Enter pennies: "); int pennies = in.nextInt(); register.enterPayment(dollars, quarters, dimes, nickels, pennies); System.out.print("Your change: "); System.out.println(register.giveChange()); } }
- P4.12 Split a number by digits
Write a program that reads in an integer and breaks it into a sequence of individual digits in reverse order. For example, the input 16384 is displayed as
4 8 3 6 1
You may assume that the input has no more than five digits and is not negative.
Define a class DigitExtractor
:
public class DigitExtractor { private int number; /** Constructs a digit extractor that gets the digits of an integer in reverse order. @param anInteger the integer to break up into digits */ public DigitExtractor(int anInteger) { . . . } /** Removes the right most digit from number, and returns it. @return the next digit */ public int nextDigit() { . . . } }
In your main class DigitPrinter, call System.out.println(myExtractor.nextDigit()) five times.
DigitExtractorTester.java
public class DigitExtractorTester { /* * Creates a DigitExtractor with a 5 digit number * and prints the results of 5 calls of the * nextDigit method. It should print the last * digit first and the first digit last */ public static void main(String[] args) { //your code here } }
- P4.15 Write large letters.
Writing large letters. A large letter H can be produced like this:
* * * * ***** * * * *
Use the class:
public class LetterH { public String toString() { return "* *\n* *\n*****\n* *\n* *\n"; } }
Define similar classes for the letters E, L, and O. Then write the message
H E L L 0
in large letters.
Your main class should be called HelloPrinter
.
- P4.18 Gauss' Easter Algorithm
Write a class to compute the date of Easter Sunday. For the Western Church, Easter Sunday is the first Sunday after the first full moon of spring (the Eastern Church uses a different method which you can read about here ). Use this algorithm, invented by the mathematician Carl Friedrich Gauss in 1800 (For more info on the history of the computation of Easter, read about Computus ):
Let y be the year (such as 1800 or 2001). Divide y by 19 and call the remainder a. Ignore the quotient. Divide y by 100 to get a quotient b and a remainder c. Divide b by 4 to get a quotient d and a remainder e. Divide 8 * b + 13 by 25 to get a quotient g. Ignore the remainder. Divide 19 * a + b - d - g + 15 by 30 to get a remainder h. Ignore the quotient. Divide c by 4 to get a quotient j and a remainder k. Divide a + 11 * h by 319 to get a quotient m. Ignore the remainder. Divide 2 * e + 2 * j - k - h + m + 32 by 7 to get a remainder r. Ignore the quotient. Divide h - m + r + 90 by 25 to get a quotient n. Ignore the remainder. Divide h - m + r + n + 19 by 32 to get a remainder p. Ignore the quotient.
Then Easter falls on day p of month n. For example, if y is 2001:
a = 6 g = 6 r = 6 b = 20 h = 18 n = 4 c = 1 j = 0, k = 1 p = 15 d = 5, e = 0 m = 0
Therefore, in 2001, Easter Sunday fell on April 15, since n=4 and p=15. Write a class Easter
with methods getEasterSundayMonth
and getEasterSundayDay
.
Use the following class as your tester class:
/** This program tests the Easter class. */ public class EasterTester { public static void main(String[] args) { Easter myEaster = new Easter(2001); System.out.print("Month: " + myEaster.getEasterSundayMonth()); System.out.println(" Expected: 4"); System.out.print("Day: " + myEaster.getEasterSundayDay()); System.out.println(" Expected: 15"); Easter myEaster2 = new Easter(2012); System.out.print("Month: " + myEaster2.getEasterSundayMonth()); System.out.println(" Expected: 4"); System.out.print("Day: " + myEaster2.getEasterSundayDay()); System.out.println(" Expected: 8"); Easter myEaster3 = new Easter(2016); System.out.print("Month: " + myEaster3.getEasterSundayMonth()); System.out.println(" Expected: 3"); System.out.print("Day: " + myEaster3.getEasterSundayDay()); System.out.println(" Expected: 27"); } }