为什么这个位移右移操作似乎没起作用?

10

有人能解释一下为什么掩码根本没有向右移动吗?您可以使用任何内容替换那个1,结果将是相同的。

unsigned mask = ~0 >> 1;
printf("%u\n", mask);
4个回答

26

这是一个类型问题。如果你将0转换为无符号类型,它就会正常:

unsigned mask = ~ (unsigned) 0 >> 1;
printf("%u\n", mask);

根据评论进行编辑:或者使用无符号字面量表示,这种表示更加简洁。

unsigned mask = ~0u >> 1;
printf("%u\n", mask);

2
"无符号掩码= ~0u >> 1;"。 u后缀表示无符号整数。 - Skizz
1
太棒了!这个问题对我来说很困难,因为我没有意识到隐式类型转换正在进行。之前的答案没有明确说明这一点。 - Jon Ericson
1
这里没有隐式转换,0 是 int;~0 是负整数,将负整数向右移位会复制符号。 - vonbrand

13

符号扩展

发生的情况是~0是一个所有位都设置为1的int(-1)。现在你向右移动1位;由于它是-1,符号扩展保持最高位设置,因此它仍然是有符号的(这不是你期望的结果)。然后它被转换为无符号的,就像你期望的那样。


4

试试这个:

unsigned mask = (unsigned) ~0 >> 1;
printf("%08x\n", mask);

如果没有进行强制类型转换,赋值语句的右侧将被视为有符号数。这意味着,在没有进行类型转换的情况下,你可能会看到符号扩展的现象。(我还将您的打印语句更改为十六进制显示,这对我来说更容易理解。)


2

~0是一个全为1的字符串。>>运算符将它们向右移位,在有符号值中,它将1移入高位比特。因此,您可以任意移位,结果不会改变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接