为什么在Java中-1右移1 = -1?

时间:2013-12-09 10:43:55

标签: java bit-manipulation

我遇到了问题"Why is -1 zero fill right shift 1=2147483647 for integers in Java?"

我从上面的问题的答案中完全理解了零填充右移的概念。但是当我试图找到-1>> 1时,我得到的答案非常复杂,我觉得很难理解。

-1 in binary form is as follows: 11111111111111111111111111111111
After flipping the bits, I got:  00000000000000000000000000000000
Upon adding 1 to it, I got:      00000000000000000000000000000001
Now shifting one position right: 00000000000000000000000000000000 
After flipping the bits, I got:  11111111111111111111111111111111
Now adding 1 to it:              00000000000000000000000000000000

我不明白-1>> 1本身是-1,那么?

2 个答案:

答案 0 :(得分:3)

>>是一个'签名右移'运算符,因此它将保留最左边的位。

因为-1(dec)是0xb11111111111111111111111111111111(bin),使用>>右移它会保留1,结果又会0xb11111111111111111111111111111111 (bin)中。

对于无符号右移,可以使用运算符>>>。它总是填满零(0)。在您的情况下,-1 >>> 1会产生0b011111111111111111111111111111112147483647,这是最大可能(正)32位二进制补码(并且等于Integer.MAX_VALUE)。

答案 1 :(得分:3)

当您执行正常的右移时(即使用>>,也称为算术右移,而不是>>>,这是逻辑右移),数字符号扩展

其工作原理如下:

当我们右移时,我们会在数字前面找到一个空位,如下所示:

 11111111111111111111111111111111
 ?1111111111111111111111111111111(1)  (right-shift it one place)

最后1被移出,?

现在,我们如何填写?取决于我们如何转变。

如果我们执行逻辑转换(即>>>),我们只需填写0即可。 如果我们进行算术移位(即>>),我们用原始数字的第一位填充它,即符号位(因为它是{{如果数字为负数,则为1}},如果不是,则为1。这称为符号扩展。

因此,在这种情况下,0-1 >> 1符号扩展到1,保留原始?

进一步阅读: