【问题标题】:bit manipulation: clearing range of bits位操作:清除位范围
【发布时间】:2013-04-04 16:40:04
【问题描述】:

我正在准备使用 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 &lt;&lt; i) 的作用,但我不确定从该值中减去 1 会如何影响位(即(1 &lt;&lt; i) - 1))。

我基本上对第二个函数有同样的困惑。从((1 &lt;&lt; (i+1)) 中减去 1 会产生什么影响,特别是对位的影响?据我了解,((1 &lt;&lt; (i+1)) 产生一个“on”位,向左移动 i+1 次——将其减去 1 有什么作用?

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

对于那些偶然知道我所引用的文字的人,它在第 5 版的第 91 页上。

【问题讨论】:

标签: c bit-manipulation


【解决方案1】:

假设i= 5

(1 &lt;&lt; i) 给你0100000 1 放在第 6 位的位置

所以现在如果我们从中减去1,那么我们得到0011111 ==> 只有第5位设置为1,其他设置为0,这就是我们得到掩码的方式

结论:对于i(1 &lt;&lt; i) -1 会给你一个掩码,其中i 的第一位设置为1,其他位设置为0

【讨论】:

  • 很好的答案和很好的解释
  • @MOHAMED 你能进一步解释为什么减法会这样吗?笼统地说,我的意思是……幕后发生了什么?有没有办法证明任何i 的结果?
  • @tomasyany 它遵循您以二进制计数的方式:0、1、10、11、100、101、110、111、1000 等等。请注意,当您从任何 100...00 数字后退一步时,您会得到一个少一位数的 11..11。
【解决方案2】:

第一个问题:

让我们说i = 5

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

因此,带有此掩码的&amp; 会将最高有效位清除为 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

因此,带有此掩码的 &amp; 会清除索引 i 之前的位

【讨论】:

    【解决方案3】:

    第一个功能:

    我们以i=3 为例。 (1 &lt;&lt; i) 将产生二进制的1000。从中减去 1 会得到二进制的 0111(这是 i 的个数)。与数字相加将清除除最后 i 位之外的所有位,就像函数描述中所说的那样。

    第二个功能:

    对于第二个功能,同样适用。如果i=3,那么((i &lt;&lt; (i+1)) - 1) 给我们01111。波浪号反转位,所以我们有10000。这样做很重要,而不是仅仅将i 位左移,因为在我们的掩码之前可能有任意数量的有效位(所以10000 可能是 8 位长,看起来像11110000。这就是波浪号让我们明白,只是为了清楚)。然后,将数字与最终结果的掩码进行与运算

    【讨论】:

      【解决方案4】:

      // 要清除从最高有效位到 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
      

      【讨论】:

      • 很好的答案,超级清晰!尽管仅供参考,但您在 clearBitsIthrough0 的第一行缺少一个结束括号
      猜你喜欢
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多