Java中的Shift运算符

ana*_*kin 6 java bit-shift

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

例如,

int i = 2; 
int j = i<<34;
System.out.println(j);
Run Code Online (Sandbox Code Playgroud)

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

mel*_*okb 6

我不确定这方面的来源,但根据WikiPedia(强调我的):

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

编辑: 看起来WikiPedia条目基本上直接从Java规范中提取信息.


AJ.*_*AJ. 3

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