位操作:清除位范围

时间:2013-04-04 16:40:04

标签: c bit-manipulation

我正准备采访Gayle Laakman McDowell撰写的文章“Cracking the Coding Interview”。在涉及位操作的部分中,提供了两个函数,但我不太明白它是如何工作的。

// To clear all bits from the most significant bit through i (inclusive), we do:
int clearMSBthroughI(int num, int i) {
    int mask = (1 << i) - 1;
    return num & mask;
}

// To clear all bits from i through 0 (inclusive), we do:
int clearBitsIthrough0(int num, int i) {
    int mask = ~(((1 << (i+1)) - 1);
    return num & mask;
}

在第一个函数中,我理解(1 << i)当然做了什么,但我不确定的是从这个值中减去1如何影响比特(即(1 << i) - 1))。

我基本上与第二个功能有同样的困惑。特别是在比特上,从((1 << (i+1))中减去1的影响是什么?根据我的理解,((1 << (i+1))导致单个“开”位,向左移动i + 1次 - 用1减去这个数字吗?

谢谢,我希望这很清楚!如果还有其他问题,请告诉我。

对于那些偶然得到我正在引用的文本的人来说,它是在第5版的第91页。

4 个答案:

答案 0 :(得分:24)

我们假设i= 5

(1 << i)给你0100000 1位于第6位位置

现在,如果我们从中减去1,那么我们会得到0011111 ==&gt;只有5个第一位设置为1而其他位设置为0,这就是我们获取掩码的方式

结论:对于给予i(1 << i) -1将为您提供一个掩码,其中i首位设置为1,其他位设置为0 < / p>

答案 1 :(得分:6)

对于第一个问题:

让我们说i = 5

(1 << i )    = 0010 0000 = 32 in base 10
(1 << i ) -1 = 0001 1111 = 31 

因此带有此掩码的&会将最高有效位清除为i,因为上面的所有位位置(包括索引i)都将为0,任何波纹管都将为1.

关于第二个问题:

再说一次i = 5

  (1 << (i + 1))      = 0100 0000 = 64 in base 10
  (1 << (i + 1)) - 1  = 0011 1111 = 63
~((1 << (i + 1)) - 1) = 1100 0000 = 192

所以带有此掩码的&会将位清除为索引i

答案 2 :(得分:4)

第一个功能:

我们以i=3为例。 (1 << i)将以二进制格式生成1000。从中减去1可以得到二进制0111(即1的数字)。对数字进行AND运算将清除除最后一位之外的所有内容,就像函数描述所说的那样。

第二功能:

对于第二个功能,同样适用。如果i=3,则((i << (i+1)) - 1)会向我们提供01111。波浪号将比特反转,因此我们有10000。这样做很重要,而不是仅仅移位i位,因为在我们的掩码之前可能有任意数量的有效位(因此10000可能是8位长,看起来像{{1这是代字号给我们带来的,只是为了清楚)。然后,数字与最终结果的掩码进行AND运算

答案 3 :(得分:3)

//要清除从最高位到i(包括)的所有位,我们执行:

int clearMSBthroughI(int num, int i) {
    int mask = (1 << i) - 1;
    return num & mask;
}

Take the example of i = 3
1<<3 gives you 0x00001000 
(1<<3)-1 gives you 0x00000111
num & (1<<i)-1 will clear the bits from msb to i

//要清除从i到0(包括)的所有位,我们执行:

int clearBitsIthrough0(int num, int i) {
    int mask = ~(((1 << (i+1)) - 1);
    return num & mask;
}

i = 3的相同例子给你

1 <<(3+1) =0x00010000
1 <<(3+1)-1 = 0x00001111
mask =~(1<<(3+1)-1) = 0x11110000
num & mask will cleaR the bits from 0 throuh i