I can't seem to understand why does -1 isn't getting changed under bitwise shift.
why does -1>>1=-1?

- 2,119
- 4
- 39
- 59
-
Which language? `>>` has different semantics in C, C++, Java and many other languages – phuclv Nov 26 '14 at 16:11
-
possible duplicate of [Shift operator in C](http://stackoverflow.com/questions/7622/shift-operator-in-c) – phuclv Nov 26 '14 at 16:14
-
http://stackoverflow.com/questions/20468564/why-is-1-right-shift-1-1-in-java – phuclv Nov 26 '14 at 16:23
3 Answers
The negative nos. are stored in the form of 2's complementin the memory. So, if you have a no. -5 it will be stored as: 1111 1011
and 2's complement of -1 is: 1111 1111 So, when you right shift it you get 1111 1111 that is again -1.
Note:
1.While storing negative no. MSB is used as sign bit. 0 indicates positive no. and 1 indicates negative no.
2.When you right shift a positive no. a 0 is added to the left and for negative nos. 1 is added to keep the sign.

- 66
- 6
A signed bit shift doesn't just shift the bits for negative numbers. The reason for this is you would get the wrong result. -1 in twos complement has all the bits set i.e. it's:
111111...1
If you were to just shift this you'd get:
011111....1
In two's complement this would be the representation of the largest positive number instead of anything that you might expect, it's the same for any negative number simply shifting would make the number positive. A simple way of implementing a right shift in twos complement is this:
rightShiftVal(int val) {
if (int < 0) {
int res = ~val; //not the value.
res = res >> 1; //do the right shift (the direction of the shift is correct).
res = ~res; //Back to twos complement.
return res;
}
return val >> 1;
}
If you put -1 into the above algorithm (i.e. 11111...111) when you not the value you get 0, when you shift the value you get 0, then when you not 0 you back to 11111....111, the representation of -1. For all other values the algorithm should work as expected.
Update
As suggested in one of the other answers you can also shift right and add the bit on at the far left i.e.
if (val < 0) {
unsigned uVal = val;
uVal = (uVal >> 1);
uVal = uVal | 0x80000000; //bitwise or with 1000...0
return uVal
}
Note that for this to work you have to put your int
into an unsigned int
so it doesn't do the signed bit shift. Again if you work through this with the value 11111...1 (the representation of -1) you are left with 11111....1, so there is no change.

- 1
- 1

- 4,063
- 2
- 18
- 30