<<
当移位位的值大于数据类型的总位数时,移位运算符如何工作?
例如,
int i = 2;
int j = i<<34;
System.out.println(j);
整数的大小是 32 位,但是我们正在移动 34 位。这是如何运作的?
我不确定这方面的来源,但根据维基百科(强调我的):
如果左侧操作数的提升类型是 int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数经过按位逻辑与运算符 & 与掩码值 0x1f (0b11111)。[4] 因此,实际使用的移位距离始终在 0 到 31 的范围内,包括 0 到 31。
编辑: 看起来维基百科条目基本上直接从Java Specification中提取了信息。
当您使用 << 或 >> 运算符对整数进行移位且移位距离大于或等于 32 时,您将移位距离 mod 32(换句话说,您屏蔽除移位的低 5 位之外的所有位)距离)。
这可能非常违反直觉。For example (i >> 32) == i
, 对于每个整数 i。您可能期望它将整个数字向右移动,对于正输入返回 0,对于负输入返回 -1,但事实并非如此;它只是返回 i,因为
(i << (32 & 0x1f)) == (i << 0) == i
.
回到你原来的问题,(i << 33) == (i << (33 & 0x1f)) == (i << 1)。如果你愿意,你可以用二进制来完成所有的事情。二进制的 270 是:0000 0000 0000 0000 0000 0001 0000 1110 右移 1,你得到:0000 0000 0000 0000 0000 0000 1000 0111 即 135。
但是在你的脑海中解决这个问题的更好方法是完全放弃二进制文件。i >> s is floor(i / 2<sup>s</sup>)
(其中 s 已被屏蔽,因此小于 32) 的值。所以, 270 << 1 = floor(270/2) = 135
。
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
If you try 1 << 34
, you end up with 4
. The runtime basically has an implicit mod NUMBER_OF_BITS
on the right-hand operand of the shift. In the previous example, it's 1 << (34 % 32)
, which becomes 1 << 2
, which is 4.