6

<<当移位位的值大于数据类型的总位数时,移位运算符如何工作?

例如,

int i = 2; 
int j = i<<34;
System.out.println(j);

整数的大小是 32 位,但是我们正在移动 34 位。这是如何运作的?

4

3 回答 3

6

我不确定这方面的来源,但根据维基百科(强调我的):

如果左侧操作数的提升类型是 int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数经过按位逻辑与运算符 & 与掩码值 0x1f (0b11111)。[4] 因此,实际使用的移位距离始终在 0 到 31 的范围内,包括 0 到 31。

编辑: 看起来维基百科条目基本上直接从Java Specification中提取了信息。

于 2013-11-11T05:45:32.567 回答
4

当您使用 << 或 >> 运算符对整数进行移位且移位距离大于或等于 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

于 2013-11-11T05:48:48.090 回答
1

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.

于 2013-11-11T05:44:17.067 回答