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

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

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

有没有办法迫使0在右移?

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

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

谢谢

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

不,你不能。

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

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

这是C99标准所说的内容(第6.5.7节):

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

E1 << E2的结果是E1左移E2位位置; 腾出的位用零填充。 如果E1具有无符号类型,则结果的值为E1 ×2 E2 ,比结果类型中可表示的最大值减少一个模数。 如果E1具有带符号类型和非负值,并且E1 ×2 E2可在结果类型中表示,那么这就是结果值; 否则,行为未定义。

E1 >> E2的结果是E1右移E2位的位置。 如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2 E2的商的整数部分。 如果E1具有带符号类型和负值,则结果值是实现定义的。

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

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

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

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