0

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

Ravid Goldenberg
  • 2,119
  • 4
  • 39
  • 59

3 Answers3

1

Because >> operator is a signed right shift operator which fills in the bit by moving it by 1 with the sign bit in your case. See this for brief discussion.

SMA
  • 36,381
  • 8
  • 49
  • 73
1

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.

Suri
  • 66
  • 6
1

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.

Community
  • 1
  • 1
James Snook
  • 4,063
  • 2
  • 18
  • 30