分配时的Bitshift对变量没有影响

时间:2016-11-16 20:49:12

标签: c bit-manipulation bit-shift

我以为我在this answer中发现了类似的东西,但在这种情况下,他们没有将表达式的结果赋给变量。在我的情况下,我正在分配它,但表达式的bitshift部分没有效果。

unsigned leftmost1 = ((~0)>>20);
printf("leftmost1 %u\n", leftmost1);

返回

leftmost1 4294967295

尽管

unsigned leftmost1 = ~0;
leftmost1 = leftmost1 >> 20;
printf("leftmost1 %u\n", leftmost1);

给我

leftmost1 4095

我希望将逻辑分成两行没有影响,为什么结果不同?

4 个答案:

答案 0 :(得分:6)

在第一种情况下,您正在进行签名的右移,因为~0会产生签名值。签名右移的确切行为是实现定义的,但是大多数平台(包括你的平台)都会扩展符号位,因此对于“全部”的输入,移位是无操作。

在第二种情况下,您正在执行无符号右移,因为leftmost1unsigned值。所以你从左边移动了零。

如果你想在没有中间任务的情况下进行无符号移位,你可以这样做:

(~0u) >> 20

u后缀表示无符号文字。

答案 1 :(得分:3)

~0int。所以你的第一段代码不等于第二段,它相当于

int tmp = ~0;
tmp = tmp >> 20;
unsigned leftmost1 = tmp;

当你右移一个负数时,你会看到符号扩展的结果。

答案 2 :(得分:2)

尝试像这样投射。 〜0被提升为 int,这是签名所以当你转移时它带有符号位

unsigned leftmost1 = ((unsigned)(~0)>>20);
printf("leftmost1 %u\n", leftmost1);

答案 3 :(得分:2)

0的类型为int。典型的双补机上~0-1。右移负数具有实现定义的结果,但常见的选择是移入1位,-1使数字保持不变(即-1 >> anything为{{1}再次)。

您可以通过编写-1(类型为0u的文字)来解决此问题。这会强制操作在unsigned int中完成,如第二个示例所示:

unsigned int

此行等同于unsigned leftmost1 = ~0; ,它隐式地将-1(带符号的int)转换为unsigned leftmost1 = -1。然后,以下操作(UINT_MAX)使用无符号算术。