Why is -1 right shift 1 = -1 in Java?

你说的曾经没有我的故事 提交于 2019-12-07 04:42:38

问题


I came across the question "Why is -1 zero fill right shift 1=2147483647 for integers in Java?"

I understood the concept of zero fill right shift perfectly well from the above question's answer. But when I tried to find -1>>1, I am getting a totally complex answer which I felt difficult to understand.

-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

I don't understand how -1>>1 is -1 itself, then?


回答1:


When you do a normal right-shift (i.e. using >>, also known as an arithmetic right shift, as opposed to >>>, which is a logical right shift), the number is sign extended.

How this works is as follows:

When we right-shift we get an empty spot in front of the number, like so:

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

The last 1 is shifted out, and in comes the ?.

Now, how we fill in the ? is dependent on how we shift.

If we do a logical shift (i.e. >>>), we simply fill it with 0. If we do a arithmetic shift (i.e. >>), we fill it with the first bit from the original number, i.e. the sign bit (since it's 1 if the number is negative, and 0 if not). This is called sign extension.

So, in this case, -1 >> 1 sign-extends the 1 into the ?, leaving the original -1.

Further reading:

  • Arithmetic shift on Wikipedia
  • Logical shift on Wikipedia



回答2:


>> is a 'signed right shift' operator, so it will preserve the leftmost bit.

So as -1 (dec) is 0xb11111111111111111111111111111111 (bin), right shifting it using >> will preserve the 1 and the result is again 0xb11111111111111111111111111111111 (bin).

For unsigned right shift, the operator >>> can be used. It always fills up with zeroes (0). In your case, -1 >>> 1 results in 0b01111111111111111111111111111111, or 2147483647, which is the largest possible (positive) 32 bit two's complement (and equal to Integer.MAX_VALUE).



来源:https://stackoverflow.com/questions/20468564/why-is-1-right-shift-1-1-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!