用点掩码计数

时间:2014-09-25 18:37:38

标签: c++ c bit-manipulation

我正在寻找一种枚举符合某个位掩码的值的方法。

例如,我想枚举包含模式0xb5的所有字节。

实现这一目标的简单C程序是:

#include <stdio.h>
#include <stdint.h>

/* prints out b5, b7, bd, bf, f5, f7, fd, ff */
int main(int argc, const char ** argv) {    
    const uint8_t mask = 0xb5;
    uint8_t i = 0;

    while(true) {
        if((i & mask) == mask) printf("%x\n", i);
        if(i == UINT8_MAX) break;
        i++; /* Replace by something smarter. */
    }    
    return 0;
}

但是,无论掩码如何,此循环都将迭代UINT8_MAX次。是否有一个巧妙的位技巧可以用来自动将i增加到满足掩码的下一个值?

3 个答案:

答案 0 :(得分:4)

您只能通过“通配符”进行计数,如下所示:

x = (x + 1) | pattern;

假设您从pattern开始(通配符位全为零)。

这里的想法是“模式位”是1,所以当你添加一个时,进位(如果有的话)通过它们到达“通配符位”的下一部分。当然,当一个进位经过时,会将“模式位”保留为0,因此它们会被放回去。

答案 1 :(得分:0)

而不是i++,您可以使用i = ((i << 1) | 1);

答案 2 :(得分:0)

@harold

陈述的主题略有不同
while (1) {
  printf("%x\n", i);  // no need for mask test
  if (i == UINT8_MAX)
    break;
  do {
    i++;
   } while ((i & mask) != mask);
}