使用右移操作无法更改-1

时间:2014-11-26 13:16:12

标签: bit-manipulation bit-shift

我似乎无法理解为什么-1在按位移位时不会改变。 为什么-1>>1=-1?

3 个答案:

答案 0 :(得分:1)

因为>> operator是一个带符号的右移运算符,它通过在你的情况下用符号位将它移动1来填充该位。有关简要讨论,请参阅this

答案 1 :(得分:1)

负面的。以2的补码形式存储在存储器中。 所以,如果你没有。 -5它将被存储为: 1111 1011

和-1的2的补码是:1111 1111 因此,当你右移它时,你得到的是1111 1111,这也是-1。

注意:

1.存储否定否。 MSB用作符号位。 0表示正数。 1表示否定号。

2.当你正确转移正面没有。左边增加0,负数增加0。添加1以保留标志。

答案 2 :(得分:1)

有符号位移不只是将位移位为负数。原因是你会得到错误的结果。在二进制补码中-1为所有位设置,即它是:

111111...1

如果你只是转移它,你会得到:

011111....1

在二进制补码中,这将是最大正数的表示,而不是您可能期望的任何东西,对于任何负数而言,只需移位就会使数字为正数。在二进制补码中实现右移的一种简单方法是:

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;
}

如果你把-1加入上面的算法(即11111 ... 111),当你没有得到0的值时,当你移动值得0时,那么当你没有0时你回到11111 ... .111,-1的表示。对于所有其他值,算法应按预期工作。

更新

正如在其他一个答案中所建议的那样,你也可以向右移动并在最左边添加位。即

if (val < 0) {
  unsigned uVal = val;
  uVal = (uVal >> 1);
  uVal = uVal | 0x80000000; //bitwise or with 1000...0
  return uVal
}

请注意,要实现此功能,您必须将int放入unsigned int,这样才能执行有符号的位移。再次,如果你使用值11111 ... 1(-1的表示)来处理它,你将留下11111 .... 1,所以没有变化。