我正在寻找一种枚举符合某个位掩码的值的方法。
例如,我想枚举包含模式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
增加到满足掩码的下一个值?
答案 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);
}