我似乎无法理解为什么-1在按位移位时不会改变。
为什么-1>>1=-1?
答案 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,所以没有变化。