【问题标题】:How to use bit manipulation to find 5th bit, and to return number of 1 bits in an integer如何使用位操作来查找第 5 位,并返回整数中 1 的位数
【发布时间】:2014-03-06 10:22:21
【问题描述】:

假设 Z 是一个无符号整数。使用 ~、>、&、| 、+ 和 - 提供返回所需结果的语句。

如果需要,我可以引入新的二进制值。

我有这些问题:

1.从左边 Z中提取第5位。

为此,我正在考虑做类似的事情

  x x x x x x x x 
& 0 0 0 0 1 0 0 0 
___________________

  0 0 0 0 1 0 0 0 

这对于提取第五位有意义吗?当我不知道 Z 的值时,我不完全确定如何仅使用 Z 来完成这项工作。 (我对这一切都比较陌生)。这种想法会奏效吗?

2.返回Z中1的位数

Here I kind of have no idea how to work this out. What I really need to know is how to work on just Z with the operators, but I m not sure exactly how to. 

就像我说的那样,我对此并不陌生,因此感谢您提供任何帮助。

【问题讨论】:

  • 第 5 位 - 最好从 MSBit 或 LSBit 开始 - 从 0 或 1 开始?
  • 有充分的理由从右边开始计数:它也适用于恰好更大的位串。或无限。

标签: c bit-manipulation


【解决方案1】:

问题 1

你是对的。我会做一个& 和一个>>,这样你就可以得到一个不错的 0 或 1。

result = (z & 0x08) >> 3;

但是,这可能不是绝对必要的。例如,如果您尝试检查该位是否设置为 if 条件的一部分,则可以利用 C 对任何非零值的定义为真。

if (z & 0x08)
        do_stuff();

问题 2

a whole variety of ways 可以做到这一点。根据该页面,以下方法可以追溯到 1960 年,尽管它直到 1988 年才以 C 语言发布。

for (result = 0; z; result++)
        z &= z - 1;

这种方法的确切原因起初可能并不明显,但如果您通过几个示例来研究,您很快就会明白为什么会这样。

值得注意的是,此操作(确定数字中 1 的数量)对于命名(人口计数或Hamming weight)以及在最近的 Intel 和 AMD 处理器上命名为 dedicated instruction 非常重要。如果您使用的是 GCC,则可以使用 __builtin_popcount 内在函数。

【讨论】:

    【解决方案2】:

    问题 1 看起来是对的,但你应该通过将结果右移 4 来获得掩码之后的位来完成它。

    要实现掩码,您需要知道单个第 5 位表示什么整数。顺便说一下,这个数字是 2^5 = 32。所以您可以将 z 与 32 相加,然后将其右移 4。

    问题 2:

    int answer = 0;
    while (z != 0){  //stop when there are no more 1 bits in z
    
       //the following masks the lowest bit in z and adds it into answer
       //if z ends with a 0, nothing is added, otherwise 1 is added
       answer += (z & 1);
       //this shifts z right by 1 to get the next higher bit
       z >>= 1;
    }
    return answer;
    

    【讨论】:

    • 谢谢。对于第一个问题,我将如何在 Z 上做类似的事情?您能否解释一下为什么要在 while 循环中执行所有这些操作?
    【解决方案3】:

    要找出第五位的值,您不必关心底部位,因此您可以摆脱它们:

    unsigned int answer = z >> 4;
    

    第五位成为底部位,因此您可以使用按位与将其去掉:

    answer = answer & 1;
    

    要查找数字中 1 位的数量,您可以应用 stakSmashr 的解决方案。如果您知道需要计算大量整数中的位数,则可以进一步优化 - 预先计算每个可能的 8 位数中的位数并将其存储在表中。表中只有 256 个条目,因此不会占用太多内存。然后,您可以一次遍历一个字节的数据并从表中找到答案。这种查找将比在每个位上再次循环更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-12
      • 2023-02-01
      • 2011-06-23
      • 2017-07-11
      • 1970-01-01
      • 2011-10-03
      • 2015-12-21
      • 2019-12-30
      相关资源
      最近更新 更多