2014-08-28 51 views
2

我与换挡玩,我让陷入困境的一个案例:转移超过类型位大小

int maxint = Integer.MAX_VALUE; 
    LOG.debug("maxint << 31 ---> {} ({})", maxint << 31 , Integer.toBinaryString(maxint << 31)); 
    LOG.debug("maxint << 32 ---> {} ({})", maxint << 32 , Integer.toBinaryString(maxint << 32)); 
    LOG.debug("maxint << 33 ---> {} ({})", maxint << 33 , Integer.toBinaryString(maxint << 33)); 

和它打印:

maxint << 31 ---> -2147483648 (10000000000000000000000000000000) 
maxint << 32 ---> 2147483647 (1111111111111111111111111111111) 
maxint << 33 ---> -2 (11111111111111111111111111111110) 

所以问题是,如果移位31个叶“1”在MSB处,班次32不应移出并返回0?

进一步说我做了同一起跑线轮班31的结果(这是Integer.MIN_VALUE的)和1

int minInt = -2147483648; 
    LOG.debug("minInt << 1 ---> {} ({})", minInt << 1 , Integer.toBinaryString(minInt << 1)); 
    LOG.debug("minInt << 2 ---> {} ({})", minInt << 2 , Integer.toBinaryString(minInt << 2)); 

转移和它打印:

minInt << 1 ---> 0 (0) 
minInt << 2 ---> 0 (0) 

这是我所期望。

回答

7

http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19

如果左边的操作数的提升的类型为int,只有五个 右手操作数的最低阶位被用作移位 距离。就好像右边的操作数受掩码值0x1f (0b11111)的 按位逻辑AND运算符&(第15.22.1节)的影响。因此实际使用的换档距离始终在 范围0至31(含)范围内。

和类似的六位长。这种行为也是允许的,并且通常在C和C++中实现,尽管在Java中不是必需的。

也有Shift operator in Java bizarre program output的重复,这是我第一次搜索错过。

2

轮班国防部32 a << b == a <<(b % 32)

PS:对于长国防部64

+0

小心一点。这只适用于正数。 '-1%32 = -1' – harold 2014-08-28 12:53:52