循环通过位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在线为您服务。