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



据我所知,当您在C中使用左移位操作符时,可以保证空位将被0填充。然而,我读到右移位是与实现相关的,这意味着在一些机器中,空位将被0填充,在另一些机器中,它们将被1填充。

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

是否有办法强制0在正确的班次上使用?

一种解决方案是,在应用右移之后,创建一个像011111111这样的掩码,然后应用位与操作,这将把插入的最左边的1更改为0。

但是这很麻烦而且浪费时间。如果有一种方法可以告诉我的机器用15来填充正确的班次,那就容易多了。

谢谢

将数字转换为unsigned,然后进行移位。这将强制0-fill

不行。

unsigned类型上的移位是定义良好的(只要右操作数是非负的且小于左操作数的宽度),并且它们总是零填充。

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

C99标准是这样说的(第6.5.7节):

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

E1 << E2 E1 left-shifted E2 位置;空出的位被0填充。如果E1有unsigned类型,结果值为E1 x2 E2,再化简模1结果类型中可表示的最大值。如果E1E1 x2 E2在结果类型,那就是结果值;否则,行为未定义 E1>>E2E1右移的E2位。如果E1有unsigned类型,或者E1具有signed类型和非负值,结果的值为E1/商的整部分2 <一口> E2 吃饭。如果E1是有符号类型且为负值,则返回值由实现定义。

11年后回到这个答案,实现当然可以提供一个选项来控制实现定义的转换的行为。我不知道有哪一家这样做。

我引用了C99标准。我认为在以后的版本中没有任何相关的变化。

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

逻辑移位用于c中的无符号数,它总是用零填充高位。这就是你需要的。

算术移位用于有符号数,因为它保留了被移位数的符号。如果数字是正数,那么最高有效位将是0,并且它将被0填充。如果数字是负数,则最高有效位为1,因此它将被1填充。

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

最新更新