【问题标题】:Bit Manipulation (extract 5th bit from X and return number of 1 bits in X)位操作(从 X 中提取第 5 位并返回 X 中 1 的位数)
【发布时间】:2014-03-07 16:09:17
【问题描述】:

假设 X 是一个无符号整数,我将如何从 X 中提取第 5 位并返回 X 中 1 的数量。注意:这两个操作不相互依赖。

为了从 X 中提取第 5 位,我想使用 & 操作来做这样的事情:XXXX1X & 000010

我不太确定如何返回 X 中 1 的位数。

谢谢!

【问题讨论】:

    标签: c bit-manipulation


    【解决方案1】:

    计算 1 位的数量相对简单;您遍历数字的所有位并将设置的位数添加到一些累加器中:

    unsigned int X;     
    unsigned int count; 
    
    for (count = 0; X; X >>= 1) {
       count += X & 1;
    }
    

    它是如何工作的:

    1. 将计数初始化为 0
    2. 从 MSB(最高有效位)开始[这是当前位]
    3. 将当前位的结果加1 & 1
      • 如果设置了该位,则为 1
      • 如果该位未设置,则为 0
    4. 将 X 右移 1 位,因此当前位现在是下一个 MSB
    5. 重复步骤 3

    提取第 5 位也很简单,只需将数字 X 右移 5 并用 1 计算逻辑与:

    unsigned int fifthBit (unsigned int X) {
       return (X >> 5) & 1;
    }
    

    【讨论】:

    • 啊,我明白了,谢谢。提取第五个元素怎么样?我相信我做错了我相信在使用 & 操作完成后我可能需要移动元素。
    • 你能解释一下为什么你向右移动而不是向左移动吗?有区别吗?
    • 其实没什么区别,你也可以将1向左移5位X & (1 << 5)。我只是选择使用右移。
    • 我看到了真棒!非常感谢!
    • 根据架构,(X >> n) & 1 可以用更少或更小的指令进行编码,因为它使用 immediates 而不是将常量加载到寄存器中。它也适用于几乎所有类型,因为 (1 << N) & uint64_t 在 32 位架构中无法按计划工作。
    【解决方案2】:

    int 中查找设置位数的更短更简单的方法如下:

    int num_1_bits(unsigned int x)  // or unsigned long x; or unsigned short x;
    {
       int bitcount = 0;
       while(x)
       { 
          x &= (x - 1);
          ++bitcount;
       }
       return bitcount;
    }
    

    这是如何工作的?

    对于无符号数xx - 1 中的位序列将是x 的补码,直到x 的第一个设置位从 LSB 计数。

    即对于x = 20 [0b11100]x - 1 = 19 [0b11011]
    这里19 的位序列是20 的补码,直到20 中的第一个设置位(LSB 位置3 的第一个设置位)。

    因此,
    如果您执行x & (x - 1),此操作将消耗来自x 的一个设置位。

    因此,
    如果您想继续这样做直到x 变为0,您将需要执行与x 中的设置位一样多的次数,这反过来将为您提供x 中设置位的计数.

    这种方法更好,因为循环只会运行与x 中的1 位一样多的次数,因此不依赖于x 的数据类型。

    【讨论】:

    • 我不确定我会称之为更简单,它们看起来都差不多难度
    【解决方案3】:

    作为补充,我确切地说,如果您正在寻找效率,那么有一些内置的硬件指令可以对位执行计算(计数零:您可以推断出您有多少 1-bit)参见 article举个例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-18
      • 2019-03-18
      • 2023-02-01
      相关资源
      最近更新 更多