在读Thinking in Java 4th的过程中,遇到一个令人疑惑的地方。
If you shift a char, byte, or short, it will be promoted to int before the shift takes place, and
the result will be an int. Only the five low-order bits of the right-hand side will be used. This
prevents you from shifting more than the number of bits in an int. If you’re operating on a
long, you’ll get a long result. Only the six low-order bits of the right-hand side will be used,
so you can’t shift more than the number of bits in a long.
对于Only the five low-order bits of the right-hand side will be used.
这一句很是不解,查阅了一下中文版,发现还是没看明白。中文版的释义如下:
如果对char、byte或者short类型的数值进行移位处理,那么在移位进行之前,它们会被转换为int类型,并且得到的结果也是一个int类型的值。只有数值右端的低5位才有用。这样可防止我们移位超过int型值所具有的位数。(译注:因为2的5次方为32,而int型数值只有32位。)若对一个long类型的数值进行处理,最后得到的记过也是long。此时只会用到数值右端的低6位,以防止移位超过long型数值具有的位数。
通过Google发现了该问题的解释:为什么是“只有数值右端的低5位才有用”。
原来 Only the five low-order bits of the right-hand side will be used.
表达的意思是int型移位操作时,只有右操作数的低五位有用。这就意味着 a<<b
过程中,只用到了 b
的低5位(相当于b%32
),移位的范围限定在0~31,原因是int数据类型的大小为4字节(32bit),这样可防止移位超过int型值所具有的位数。而对于long型,由于long数据类型的大小为8字节(64bit),所以只用到又操作数二进制位的低6位,移位范围限定在0~63。
下面我们通过代码来验证一下:
public class ShiftOperator {
public static void main(String[] args) {
int i = 1;
System.out.println("i = " + Integer.toBinaryString(i));
int a = i << 31;
System.out.println("i << 31 = " + Integer.toBinaryString(a));
int b = i << 32;
System.out.println("i << 32 = " + Integer.toBinaryString(b));
int c = i << 33;
System.out.println("i << 33 = " + Integer.toBinaryString(c));
long j = 1;
System.out.println("j = " + Integer.toBinaryString(i));
long e = j << 63;
System.out.println("j << 63 = " + Long.toBinaryString(e));
long f = j << 64;
System.out.println("j << 64 = " + Long.toBinaryString(f));
long g = j << 65;
System.out.println("j << 65 = " + Long.toBinaryString(g));
}
}
控制台输出结果如下:
i = 1
i << 31 = 10000000000000000000000000000000
i << 32 = 1
i << 33 = 10
j = 1
j << 63 = 1000000000000000000000000000000000000000000000000000000000000000
j << 64 = 1
j << 65 = 10
在int移位操作中,对右操作数 31
取低5位后值仍为 31
,因此 i 的值向左移动 31 位;右操作数 32
取低5位后值位 0
,所以 i 的值不移位;右操作数 33
取低5位后为 1
,所以 i 的值只移动 1 位。long型移位操作同理,就不在赘述了。