3

我有一个特定的 C 位移场景,我认为 Stack Overflow 尚未涵盖该场景。(如果是的话,我还没找到!)

本练习使用signed ints 作为数据类型。

取值0x80000000(最高有效位仅为 1。)

使用算术右移(我的做法)在机器上将其右移一次。

结果 = 0xC0000000(最左边字节中的 1100 0000)。

继续移动它,你应该从左到右填充它们。

结果 = 0xFFFFFFFF(全部。)

但是: 尝试相同的示例,但移动一个额外的位置,全部一起:

0x80000000 >> 0x00000020(右移 32 次)

你的结果?我不知道。我的结果不是全部。事实上,我得到了0x00000001这不是我想要的行为。为什么是这样?它是特定于机器的吗?

(背景:家庭作业将我的操作限制为几个位运算符来解决难题。这是难题的一个方面,但远非整个问题。)

4

4 回答 4

6

这是未定义的行为

为什么 32 位整数的左位移“<<”在使用超过 32 次时不能按预期工作?

这意味着您应该像避免瘟疫一样避免它。这里有一些链接,包括“每个 C 程序员应该了解的未定义行为”: http: //lwn.net/Articles/511767/

于 2012-08-27T16:21:17.397 回答
5

移动操作数的位数具有未定义的行为,这就是您得到“意外”结果的原因。

于 2012-08-27T16:17:02.313 回答
2

这是来自 C99 标准的引用:

6.5.7 移位运算符 [...]

3 [...] 如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。

归功于原始来源

于 2012-08-27T16:20:15.277 回答
1

您不能移动超过其宽度的值。一个 int 数的 with 是多少?好吧,在 32 位系统中,它是 32 位的。如果您尝试在 gcc 中移动超过 32 的 int,则会收到以下警告:

warning: right shift count >= width of type [enabled by default]

如果你想得到0xFFFFFFFF你必须转移 31 次,而不是 32 次。想想看!

于 2012-08-27T16:26:23.513 回答