繁体   English   中英

右移和有符号整数

[英]Right shift and signed integer

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

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

使用如下所示的位域生成一个word

(11111111 11111111 10000000 00000000)

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

从以下链接:
INT34-C。 不要将表达式移位负数位或大于或等于操作数中存在的位数

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

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

/* Initialize ui1 and ui2 */

uresult = ui1 >> ui2;

假设右移是实现为算术(带符号)移位还是逻辑(无符号)移位也可能导致漏洞。 见建议INT13-C。 仅在无符号操作数上使用按位运算符

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

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

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

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

最新的C ++ 20草案

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM