为什么1 >> 32 == 1?

Art*_*ldt 30 java bit-manipulation

我想知道这可能是一个JVM错误吗?

java版"1.6.0_0"OpenJDK运行时环境(IcedTea6 1.4.1)(6b14-1.4.1-0ubuntu13)OpenJDK 64位服务器VM(内置14.0-b08,混合模式)

class Tmp {
    public static void main(String[] args) {
        System.out.println("1>>1 = "+(1>>1));
        System.out.println("1>>2 = "+(1>>2));
        System.out.println("1>>31 = "+(1>>31));
        System.out.println("1>>32 = "+(1>>32));
        System.out.println("1>>33 = "+(1>>33));
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时产生这个:

1>>1 = 0
1>>2 = 0
1>>31 = 0
1>>32 = 1 <---------- should be 0 i think
1>>33 = 0
Run Code Online (Sandbox Code Playgroud)

对于任何32的倍数,我也得到相同的结果.

我需要写自己的右移检查这个吗?

rwo*_*ong 31

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.1

15.19移位运算符

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

如果左侧操作数的提升类型很,则只使用右侧操作数的六个最低位作为移位距离.就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x3f的影响.因此,实际使用的移位距离始终在0到63的范围内,包括0和63.

(强调我的)


ama*_*ara 17

这不是一个错误.在n >> m,它只查看m的最后五位 - 所以任何大于31的数字都将减少到那个数字mod 32.所以,(256 >> 37) == 8是的.

编辑:如果你正在使用整数,这是真的.如果它很长,那么它会查看m 的最后六位,或者64位的mod.

  • @rwong,又错了.C++说:"如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义." 这意味着如果你这样做(1 >> 33),那么你就是在向自己的恶魔开放.Java比C++更具体,而不是更少. (4认同)
  • 那么(1 >> 32)变成(1 >> 0)?奇怪的. (2认同)