为什么在Java中-1右移1 = -1?
我遇到了一个问题“为什么-1是零填充右移1 = 2147483647对于Java中的整数?”
从上面的问题的答案中我完全理解零填充右移的概念。 但是当我试图找到-1 >> 1时,我得到一个完全复杂的答案,我觉得很难理解。
-1二进制forms如下:11111111111111111111111111111111翻转后,我得到:00000000000000000000000000000000加1后,我得到:00000000000000000000000000000001现在向右移一个位置:00000000000000000000000000000000翻转位后,我得到:11111111111111111111111111111111现在加1 :00000000000000000000000000000000
我不明白-1 >> 1本身是-1,那么?
当你进行正常的右移(即使用>>
,也称为算术右移,而不是>>>
,这是一个逻辑右移)时,数字是符号扩展的 。
这是如何工作的如下:
当我们右移时,我们会在数字前面找到一个空位,如下所示:
11111111111111111111111111111111 ?1111111111111111111111111111111(1) (right-shift it one place)
最后1
被移出,来了?
。
现在,我们如何填写?
取决于我们如何转变。
如果我们进行逻辑移位 (即>>>
),我们只需用0
填充它。 如果我们进行算术移位 (即>>
),我们用原始数字的第一位填充它,即符号位 (因为如果数字是负数则为1
,如果不是则为0
)。 这称为符号扩展。
那么,在这种情况下, -1 >> 1
符号 – 将1
扩展为?
,留下原来的-1
。
进一步阅读:
- 维基百科上的算术转换
- 维基百科的逻辑转变
>>
是一个’签名右移’运算符,因此它将保留最左边的位。
因此-1
(dec)是0xb11111111111111111111111111111111
(bin),使用>>
右移将保留1
,结果再次为0xb11111111111111111111111111111111
(bin)。
对于无符号右移,可以使用运算符>>>
。 它总是填满零(0)。 在您的情况下, -1 >>> 1
导致0b01111111111111111111111111111111
或2147483647
,这是最大可能(正)32位二进制补码(并且等于Integer.MAX_VALUE
)。