1

我正在学习C语言。我有这个代码,如果需要可以提供更多:

int result = 0;
int mask1 = 0x0000ffff;
mask1 = mask1 >> 28;

当我使用 gdb 和 print 时/x mask1,我得到0x0了,这是正确的。那为什么会这样:

int result = 0;
int mask1 = 0xffffffff;
mask1 = mask1 >> 28;

print 0xffffffff

不应该打印0x0000000f吗,因为我要左移 28 位?

它与我的 64 位机器上 int 占用的位数有关吗?我看着这个,但它并没有完全回答所有问题。

4

5 回答 5

5

负整数右移的行为是实现定义的。一种常见的行为是算术移位,它进行符号扩展。这样做的好处是右移也是除以 2 的幂(四舍五入到负无穷大),就像正数一样。

于 2012-08-30T21:58:12.820 回答
1

你在右移。这是右:>>,这是左:<<

通常,当您将(有符号)整数右移时,假定您正在更改而不是符号:这就是丹尼尔所说的符号扩展的意思。标准没有要求,并非所有平台都这样做。

实际上,在使用二进制补码的系统上,这意味着负值将用 填充新的最高位1,而正值将用填充0

例如,在 8 位 2s 补码系统上:

before          after >> 1
11111110 = -2   11111111 = -1 (so new top bit was 1)
00000010 = +2   00000001 = +1 (so new top bit was 0)
于 2012-08-30T22:07:33.937 回答
0

如果您将 0xffffffff 打印为整数,您将意识到它被视为 -1。

Bitshift 对负数的工作方式不同,因为它用 1 填充最高位。所以基本上,0xffffffff >> 1 == 0xffffffff。

如果您将掩码声明为unsigned int,那么它可能会执行您想要的操作。

于 2012-08-30T22:06:16.843 回答
0

是的,正如@veer 指出的那样,int您正在进行右算术移位,这非常适合将有符号数除以 2 的幂(以二进制补码表示):

算术右移

通过将类型更改为unsigned int它将成为右位移位,这非常适合将无符号数除以 2 的幂(这是您的方案):

右逻辑移位

Wikipedia Bitwise operation上有一些很好的解释。

于 2012-08-30T22:28:55.467 回答
0

负整数的按位右移是实现定义的。

这是做什么gcc的:

对有符号整数(C90 6.3、C99 6.5)的一些按位运算的结果。

带符号的 `>>' 通过符号扩展作用于负数。

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

于 2012-08-30T22:19:38.057 回答