我使用Java时遇到了这个问题:
int b=16;
System.out.println(b<<30);
System.out.println(b<<31);
System.out.println(b<<32);
System.out.println(b<<33);
输出: 0 0 16 32
Java的位移操作是循环的吗?如果不是,为什么当b<<30时得到0,而当b<<32时得到16?
我使用Java时遇到了这个问题:
int b=16;
System.out.println(b<<30);
System.out.println(b<<31);
System.out.println(b<<32);
System.out.println(b<<33);
输出: 0 0 16 32
Java的位移操作是循环的吗?如果不是,为什么当b<<30时得到0,而当b<<32时得到16?
位移操作不是循环操作。对于位移 int
,Java只使用5个最低有效位,因此(b << 0)
等同于(b << 32)
(等同于(b << 64)
,以此类推)。你可以将位移量除以32并取余数。
对于位移 long
,类似的情况发生,Java只使用6个最低有效位,因此(aLong << 0)
等同于(aLong << 64)
。
JLS第15.19节讨论了这一点:
如果左操作数的提升类型为int,则仅使用右操作数的最低的五个有效位作为移位距离。就好像右操作数受到按位逻辑与运算符&(§15.22.1)的影响,掩码值为0x1f (0b11111)一样。因此实际使用的移位距离总在包括0和31的范围内。当你执行 16 << 30
时,你会得到 0
,因为 16
的二进制表示中只有一个位是1。
00000000 00000000 00000000 00010000
被移动到 int
的末尾并被丢弃。
// Discarded - Result-----------------------------
(00000100) 00000000 00000000 00000000 00000000
16 << 32 & 0x1f
这相当于16。
<<
、>>
和>>>
。 - rgettman