你能控制一个按位右移将填充C吗?

时间:2011-12-07 20:19:51

标签: c bitwise-operators

据我所知,当你在C中使用左移位运算符时,它保证空位将填充为0。但是,我已经读到右移是依赖于实现的,这意味着在一些机器中空位将填充0,而在其他机器中它们将填充1。

我在程序中使用右移,实际上我的机器用1填充空位。问题是我需要用0来填充。

有没有办法强制在正确的班次使用0?

在应用右移后,一种解决方案是创建一个类似011111111的掩码,然后应用按位AND,这将更改插入的最左边的1。

但这很麻烦,浪费时间。如果有办法告诉我的机器用1s填充正确的班次,那就更容易了。

由于

3 个答案:

答案 0 :(得分:39)

将数字转换为unsigned,然后转移。这将迫使0填充。

答案 1 :(得分:17)

不,你不能。

无符号类型的移位定义良好(只要右操作数为非负数且小于左操作数的宽度),并且它们始终为零填充。

签名类型的移位(或任何按位操作)通常不是一个好主意。如果左操作数为负,则<<具有未定义的行为,>>产生实现定义的结果(意味着编译器必须记录它的作用,但是你无法控制它) 。对于有符号类型的非负值,结果就是您所期望的 - 只要它不溢出(如果它溢出,则行为未定义)。

以下是C99 standard所说的内容(第6.5.7节):

  

对每个操作数执行整数提升。类型   结果是提升左操作数的结果。如果值   右操作数为负数或大于或等于宽度   在提升的左操作数中,行为未定义。

     

E1 的结果&lt;&lt; E2 E1 左移 E2 位   位置;腾出的位用零填充。如果 E1 有未签名的   类型,结果的值是 E1 ×2 E2 ,减少模数   比结果类型中可表示的最大值。如果 E1 有   有符号类型和非负值, E1 ×2 E2 可表示   结果类型,那就是结果值;否则,   行为未定义。

     

E1 的结果&gt;&gt; E2 E1 右移 E2 位位置。如果 E1 有   无符号类型或 E1 具有签名类型和非负值,   结果的值是 E1 /的商的组成部分   2 E2 。如果 E1 具有签名类型和负值,则生成   值是实现定义的。

答案 2 :(得分:5)

有两种不同的右移操作:算术和逻辑。

逻辑移位与C中的无符号数一起使用。它总是用零填充高位。这就是你需要的。

算术移位与带符号的数字一起使用,因为它保留了移位数字的符号。如果数字为正,则最高有效位为0,并且将填充0。如果数字为负数,则最高有效位为1,因此将填充1。

请注意,在Java中,这些实际上使用不同的运算符:>>用于算术,>>>用于逻辑。这是必需的,因为Java没有无符号类型。