Java Reference
In-Depth Information
distance, save the result of the previous shift operation and shift it one more bit to the left on each
iteration. This version of the program prints 32 as expected:
public class Shifty {
public static void main(String[] args) {
int distance = 0;
for (int val = -1; val != 0; val <<= 1)
distance++;
System.out.println(distance);
}
}
The fixed program illustrates a general principle: Shift distances should, if possible, be constants .
If the shift distance is staring you in the face, you are much less likely to exceed 31 or, if the left
operand is a long , 63. Of course, it isn't always possible to use a constant shift distance. When you
must use a nonconstant shift distance, make sure that your program can cope with this problematic
case or does not encounter it.
There is another surprising consequence of the aforementioned behavior of shift operators. Many
programmers expect a right-shift operator with a negative shift distance to function as a left shift
and vice-versa. This is not the case. A right shift always functions as a right shift, and a left shift
always functions as a left shift. Negative shift distances are made positive by lopping off all but the
five low-order bits— six bits if the left operand is a long . So, for example, shifting an int to the left
with a shift distance of -1 has the effect of shifting it 31 bits to the left.
In summary, shift distances are calculated mod 32 or, if the left operand is a long , mod 64. It is
therefore impossible to shift away an entire value by using any shift operator or distance. Also, it is
impossible to perform a left shift with a right-shift operator or vice-versa. Use a constant shift
distance if possible, and exercise care if the shift distance can't be made constant.
Language designers should perhaps consider restricting shift distances to the range from 0 to the
type size in bits and changing the semantics of shifting a value by the type size to return 0. Although
this would avoid the confusion illustrated by this puzzle, it could have negative performance
consequences; Java's semantics for the shift operators are those of the shift instructions on many
processors.
< Day Day Up >
 
 
Search WWH ::




Custom Search