右移和有符号整数

时间:2011-09-22 22:46:37

标签: c++ bit-shift platform-specific

在我的编译器上,以下伪代码(用二进制替换的值):

sint32 word = (10000000 00000000 00000000 00000000);
word >>= 16;

生成word,其位域如下所示:

(11111111 11111111 10000000 00000000)

我的问题是,我可以依赖所有平台和C ++编译器的这种行为吗?

5 个答案:

答案 0 :(得分:23)

从以下链接:
INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand

不合规代码示例(右移)
E1 >> E2的结果是E1右移E2位位置。如果E1具有无符号类型或E1具有有符号类型和非负值,则结果的值是E1 / 2 E2 的商的整数部分。如果E1具有带符号的类型和负值,则结果值是实现定义的,可以是算术(带符号)的移位:
Arithmetic (signed) shift
或逻辑(无符号)班次:
Logical (unsigned) shift
这个不合规的代码示例无法测试右操作数是否大于或等于提升的左操作数的宽度,从而允许未定义的行为。

unsigned int ui1;
unsigned int ui2;
unsigned int uresult;

/* Initialize ui1 and ui2 */

uresult = ui1 >> ui2;

假设右移是实现为算术(带符号)移位还是逻辑(无符号)移位也可能导致漏洞。见建议INT13-C. Use bitwise operators only on unsigned operands

答案 1 :(得分:13)

不,你不能依赖这种行为。负数量的右移(我假设你的例子正在处理)是实现定义的。

答案 2 :(得分:6)

在C ++中,没有。它取决于实现和/或平台。

在其他一些语言中,是的。例如,在Java中,>>精确定义运算符以始终使用最左位填充(从而保留符号)。 >>>运算符使用0填充。因此,如果您需要可靠的行为,一种可能的选择是更改为其他语言。 (虽然很明显,根据您的具体情况,这可能不是一种选择。)

答案 3 :(得分:3)

AFAIK整数可以用c ++表示为符号幅度,在这种情况下,符号扩展将填充0。所以你不能依赖这个。

答案 4 :(得分:0)

来自latest C++20 draft

有符号整数类型的右移是算术右移,它执行符号扩展。