Chapter 3


Exercise 1 What happens when a comment appears inside a literal string? (Recall from Chapter 2 that a literal string is a run of text enclosed between double quotes.) What would the following line of code do?

System.out.println("A /* Did this print? */ Z");

Write a program that includes this line. Does the program print the entire literal string, or does it just print "A Z"?

Solution 1 The program prints the entire literal string. A // or /* inside a literal string doesn't signal the start of a comment.

Exercise 2 What is the value of ~100? What is the value of ~-100? First try to figure it out, and then write a program to print out the values. (Hint: You can figure it out without using pen and paper if you remember something that was discussed in Chapter 2.)

Solution 2 ~100 is -101. ~-100 is 99. Recall from Chapter 2 that to generate the negative of an integer type, invert all its bits and then add one. In other words, if you use ~ to invert an integer's bits, you have almost generated its negative. Almost, but not quite: You still have to add 1. So ~ generates the negative of its argument, minus 1.

The following program performs the computations:

public class TildeTest {   public static void main(String[] args)   {     int n = 100;     int nTilde = ~n;     System.out.println("~100 = " + nTilde);     n = -100;     nTilde = ~n;     System.out.println("~-100 = " + nTilde);   } } 

Exercise 3 Write a program that prints out the following values:

32 << 3 32 >> 3 32 >>> 3 -32 << 3 -32 >> 3 -32 >>> 3

Solution 3 The following program performs the required operations:

public class Shift32By3 {   public static void main(String[] args)   {     int x = 32 << 3;     System.out.println("32 << 3 = " + x);     x = 32 >> 3;     System.out.println("32 >> 3 = " + x);     x = 32 >>> 3;     System.out.println("32 >>> 3 = " + x);     x = -32 << 3;     System.out.println("-32 << 3 = " + x);     x = -32 >> 3;     System.out.println("-32 >> 3 = " + x);     x = -32 >>> 3;     System.out.println("-32 >>> 3 = " + x);   } }

The output is

32 << 3 = 256 32 >> 3 = 4 32 >>> 3 = 4 -32 << 3 = -256 -32 >> 3 = -4 -32 >>> 3 = 536870908

Exercise 4 What are the values of the following expressions? First do the computations mentally. Then write a program to verify your answer.

false & ((true^(true&(false|!(true|false))))^true) true | (true^false^false^true&(false|!(true&true)))

Solution 4 The first expression has the form "false & anything", so its value is false. The second expression has the form "true | anything", so its value is true. The following program verifies this:

public class AndAnythingOrAnything {   public static void main(String[] args)   {     boolean a = false & ((true^(true&(false|!(true|false))))^true);     boolean b = true | (true^false^false^true&(false|!(true&true)));     System.out.println("a = " + a);     System.out.println("b = " + b);   } }

Exercise 5 The following expression looks innocent:

boolean b = (x == 0) | (10/x > 3);

You can assume x is an int. Write a program that prints out the value of this expression for the following values of x: 5, 2, 0. What goes wrong? (You will see a failure message that you might not be familiar with, because we have not introduced it yet. Don't worry—just try to understand the general concept.) How can you make the code more robust by adding a single character to the expression?

Solution 5 The following program does what the question requires:

 1. public class Chap3Q5  2. {  3.   public static void main(String[] args)  4.   {  5.     int x = 5;  6.     boolean b = (x == 0) | (10/x > 3);  7.     System.out.println("x=" + x + ", b=" + b);  8.     x = 2;  9.     b = (x == 0) | (10/x > 3); 10.     System.out.println("x=" + x + ", b=" + b); 11.     x = 0; 12.     b = (x == 0) | (10/x > 3); 13.     System.out.println("x=" + x + ", b=" + b); 14.   } 15. }

The output from line 7 is "x=5, b=false". The output from line 10 is "x=2, b=true". You don't get any output from line 13. Instead, the JVM returns an error message. Your message may vary based on your JVM rev, but probably you saw the following:

java.lang.ArithmeticException: / by zero at Chap3Qs.main(Chap3Qs.java:12) 

When a program prints out a message like this that includes the word "Exception", you know that something has gone wrong. Exceptions are Java's mechanism for indicating program trouble or failure. They're covered in Chapter 11, "Exceptions." The stuff in parentheses at the end of the message says that something went wrong at line 12, so execution was abandoned at that point. The message and a glance at line 12 tell us that we have tried to divide 10 by zero. This is an illegal operation, because dividing by zero is undefined.

To fix the program, just change | to ||. At line 12, the "x == 0" comparison will evaluate to true, so the short-circuit operator will skip the illegal remainder of the expression.

The "Short-Circuit Operators" section of Chapter 3 explained that short-circuit operators let you avoid unnecessary execution of time-consuming code. This question shows that you can also use them to avoid unnecessary execution of code that would generate an error.

Exercise 6 The 32-bit float type is wider than the 64-bit long type. How can a 32-bit type be wider than a 64-bit type?

Solution 6 Longs (64 bits) use two's-complement data representation, and floats (32 bits) use floating-point representation. No matter what data representation is used, there are exactly 2n possible combinations of n bits. The way to think about this problem is to consider the way that represented numbers are distributed. The long type represents 264 values, evenly distributed along the number line. In other words, the distance between any two consecutive numbers represented by a long is exactly 1.

With floats, the 232 values are not evenly distributed. If you draw a dot on the number line for every number represented by a float, you see a dense cluster near zero. The farther you get from zero, the more sparsely the dots appear. Far out near the extreme positive and negative ends of the range, the dots are very rare indeed. To quantify, the smallest-magnitude float that is greater than zero—in other words, the first number to the right of zero on the number line—is 1.4 x 10-45. However, the difference between the largest float and the next-smallest float is about 2 x 1031—a truly astronomical number.

So the 32-bit float type achieves a wider range than the 64-bit long type by distributing its represented values more sparsely.

Exercise 7 Write a program that contains the following two lines:

byte b = 6; byte b1 = -b;

What happens when you try to compile the program?

Solution 7 The first line (byte b = 6;) is legal. The second line (byte b1 = -b;) is a problem. The result of the unary - operation is of type int, and the code tries to assign an int to a byte. The compilation will fail. The compiler error may vary depending on your compiler rev, but probably you will get a message that says this:

…possible loss of precision: int, required: byte…




Ground-Up Java
Ground-Up Java
ISBN: 0782141900
EAN: 2147483647
Year: 2005
Pages: 157
Authors: Philip Heller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net