按位移位澄清

时间:2011-11-11 00:34:41

标签: c binary bit-manipulation bit-shift

假设我将变量x初始化为425。在二进制文件中,即110101001

将其向右移位2,如下所示:int a = x >> 2;,答案为:106。在二进制文件中1101010。这是有道理的,因为两个最右边的位被丢弃,两个零被添加到左侧。

将其向左移位2,如下所示:int a = x << 2;,答案为:1700。在二进制文件中,这是11010100100。我不明白这是如何工作的。为什么保留最左边的两个位?我怎么能放弃它们?

谢谢,

3 个答案:

答案 0 :(得分:4)

这是因为int在您的系统上可能是32位。 (假设x是int类型。)

所以你的425实际上是:

0000 0000 0000 0000 0000 0001 1010 1001

当左移2时,你得到:

0000 0000 0000 0000 0000 0110 1010 0100

在你一直走到32之前,没有任何东西会被移除。(严格地说,在C / C ++中,有符号整数的溢出是未定义的行为。)

要删除已移位的位,您需要按照与您的数字的原始长度相同的掩码进行按位AND:

int a = (425 << 2) & 0x1ff;  //  0x1ff is for 9 bits as the original length of the number.

答案 1 :(得分:1)

首先,不要移动有符号整数。对于无符号整数类型,按位运算通常是明确无误的。

其次,如果您可以使用* 4/ 4

,为什么要转移

第三,当你超过类型的大小时,你只会丢弃左边的位。如果要以数学方式“左侧截断”,请执行模运算:

(x * 4) % 256

按位等效项是带有位模式的AND:(x << 2) & 0xFF

(也就是说,C中的基本无符号整数类型总是隐式“模2 n ”,其中 n 是数字类型的位。)

答案 2 :(得分:1)

为什么你会期望它们被删除?您的int(可能)消耗4个字节。你正在将它们转移到一个合理占据的空间。

评估过程中包含了内存中的整个4字节空间。你需要完全从内存中的那个空间移开来“贬低”它们。