循环通过位C
我试图遍历无符号字符的位,但我不知道从哪里开始,最终,我将对这些位执行其他按位操作,例如〜和xor..etc。
循环比特可以通过以下几种方式完成:
- 您可以在移动值时执行破坏性循环,并根据您要枚举位的顺序测试初始位或最终位,或者
- 当你使用按位AND来测试带有单位掩码的数字时,你可以做一个非破坏性的循环,由左移
1
。
以下是第一种方法的示例:
unsigned int bits = ...; while (bits) { if (bits & 1) { // Current bit is set to 1 } else { // Current bit is set to 0 } bits >>= 1; }
如果要在达到零后继续使用位,请创建一个单独的计数器。
以下是第二种方法的示例:
unsigned int bits = ...; for (int pos = 0 ; pos != 16 ; pos++) { if (bits & (1 << pos)) { // Current bit is set to 1 } else { // Current bit is set to 0 } }
此函数允许您遍历单词中的所有设置位:
inline size_t next_bit(uint64_t bf, size_t bit) { return ctz(bf & ~((1UL << bit) -1)); }
ctz
函数计算应由编译器作为内置函数提供的尾随零的数量。 对于gcc和llvm,您可以使用以下内容(请注意,x86上的0
未定义ctz
因此ctz
):
inline size_t ctz(uint64_t x) { return x ? __builtin_ctzll(x) : 64; }
以下是如何在for循环中使用它的示例:
for (size_t i = next_bit(bf, 0); i < 64; i = next_bit(bf, i + 1)) // the i-th bit is set.
该function通过清除第i
位之前的所有位并计算尾随零的数量来工作,这将为您提供第i
位之后的下一个设置位。 通过首先将比特移位到第i
个位置,减去将所有比特设置为低于第i
个比特的比特来完成清除比特。 然后,我们可以NOT
使用掩码来获取i
之后的所有位,以便AND
运算将删除i
之后的所有位。 ctz
完成其余的工作。
这对于一个未签名的字符有点过分(双关语)但是我无法抗拒。 老实说,对于8位字,你最好使用其他答案中提出的简单while循环。
好吧,从最低位到最高位,你可以像这样循环:
unsigned char somebyte = ...; for (int i = 0; i < 8; ++i, somebyte >>= 1) { if (somebyte & 0x1) { // Do stuff for 1 bit } else { // Do stuff for 0 bit } }
这是一个非常普遍的用例; 通常,您希望并行化您的工作(一次操作一个完整的字节),或者只对1位进行操作(当您用完而不是完成所有8个循环时停止)等等。需要更多上下文来解决具体问题。问题而不是一般循环。 通过聪明的比特笨拙的黑客攻击,可以最有效地解决许多具体问题。
#define BIT(a,b) (a & (1<
Void PrintBits(unsigned int no) { Unsigned int mask = 0x8000;//=1000 0000 0000 0000 for 16 bit integers For(I=0;I<16;I++){ If((i&mask)!=0)printf("1"); Else printf ("0"); Mask>>=1; If(i%4==0)printf (" "); } }
如果你不明白这个代码,请评论,我是24×7在线为您服务。