Java中的负数无符号右移

时间:2015-07-09 00:36:32

标签: java bit-manipulation bit-shift

我很难将头部缠绕在负无符号位运算符周围。 例如,我有以下代码。它打印出值7,我不明白为什么。

int num1 = -37, num2 = -3;    
System.out.println( num1 >>> num2);
// Essentially the same as System.out.println( -37 >>> -3); 
// I just wanted to emphasize that i am working with Integers

据我所知,二进制格式的数字-37如下所示。

11111111 11111111 11111111 11011010 = -37(十进制格式)

如果我们的无符号右移3(-37>>>>>>>>>> -3),据我所知(如果我的理论存在缺陷或缺乏关键,请纠正我概念),它将字节向右移动3,在最右侧位置出现的3位出现在翻转状态的最左侧位置(从0到1),这意味着我们得到以下结果。

00011111 11111111 11111111 11111011 = 536870907(十进制格式)。

但是,如果我们应用-3的无符号右移(-37>>> -3),我们得到结果7.我不明白它为什么返回7.有人请解释一下对我?

1 个答案:

答案 0 :(得分:0)

这似乎是违反直觉的,但是当移动int时,根据JLS, Section 15.19,仅使用移位金额的最后5位。

  

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

这意味着-3仅使用最后5位,或29。这里是-3比特来显示正在发生的事情:

11111111 11111111 11111111 11111101

最后5位为11101,或十进制为29

右移距离为29,这意味着前3位保持并一直向右移动。考虑-37

11111111 11111111 11111111 11011010

在29个位置的无符号移位后,剩下7

00000000 00000000 00000000 00000111

正如您所看到的,负移位量充其量是令人困惑的。尽量避免使用,并且总是尝试使用0到31之间的实际数字来换班int