tags:

views:

207

answers:

6

Hi, i am teaching myself java and i work through the exercises in Thinking in Java.

On page 116, exercise 11, you should right-shift an integer through all its binary positions and display each position with Integer.toBinaryString.

public static void main(String[] args) {
int i = 8;
System.out.println(Integer.toBinaryString(i));
int maxIterations = Integer.toBinaryString(i).length();
int j;
for (j = 1; j < maxIterations; j++) {
    i >>= 1;
System.out.println(Integer.toBinaryString(i));
}

In the solution guide the output looks like this:

1000
1100
1110
1111

When i run this code i get this:

1000
100
10
1

What is going on here. Are the digits cut off?

I am using jdk1.6.0_20 64bit. The book uses jdk1.5 32bit.

+8  A: 

It looks like there is an error in the book.

The right shift operation shifts all bits to the right, removing the least significant bit. This makes a lots more sense if you right align the results (by padding with zeros, for example).

00001000
00000100
00000010
00000001
00000000

The topmost bit shifted in is:

  • 0 if your number is positive
  • 1 if your number is negative.

If you want the final result to be ones then try using a negative number like -8 instead of 8.

11111111111111111111111111111000
11111111111111111111111111111100
11111111111111111111111111111110
11111111111111111111111111111111

If you use >>> instead of >> then a zero will always be shifted in, regardless of whether the number is positive or negative.

Mark Byers
It doesn't sound like an error in the book, the result is just different if you're working with 4 bits vs 8 bits (ok maybe an error since Java won't let you work with just 4 bits..).
Brendan Long
+3  A: 

It is correct that the right shift operator eventually produces a zero when given a positive integer as input.

It's best to think of it as an operation where all digits are shifted to the right, the rightmost digit is cut off and an additional zero is added to the left, i.e. the pattern is:

00001000
00000100
00000010
00000001
00000000
00000000
mikera
+3  A: 

From the bitwise operators Java Tutorials Page:

The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.

Since 8 is positive, a zero is shifted. If i was negative, a one would get shifted instead (to keep the same sign on the integer).

Ben S
+2  A: 

The right shift operator moves your bits to the right, i.e.

01000
00100
00010
00001

Right shift will "fill up" the leftmost bit with the same value it had before shifting. And since the leftmost bit is the sign, a positive value will be filled with zeros and a negative value with ones.

Stroboskop
+1  A: 

If you set the higest bit in your int like

int i = 1 << 31;

You will see the described behaviour, the sign will be retained during shift. I assume it was an example intented to illustrate the operation.

10000000000000000000000000000000
11000000000000000000000000000000
11100000000000000000000000000000
11110000000000000000000000000000
11111000000000000000000000000000
11111100000000000000000000000000
11111110000000000000000000000000
....
11111111111111111111111111111000
11111111111111111111111111111100
11111111111111111111111111111110
11111111111111111111111111111111
stacker
A: 

You seem to think that variable >>= 1 shifts a one onto the variable. The 1 actually specifies how many times to shift the variable. Signed numbers shift on whatever is in the most-significant bit position. >>> forces the number to act unsigned and always shift on zeros.

Michael Speer