循环通过位C

时间:2015-10-08 01:46:24

标签: c bit-manipulation bit

我试图循环遍历无符号字符的位,但我不知道从哪里开始,最终,我将对这些位执行其他按位操作,例如〜和xor..etc。

5 个答案:

答案 0 :(得分:6)

循环比特可以通过多种方式完成:

  • 您可以在移动值时执行破坏性循环,并根据您要枚举位的顺序测试初始位或最终位,或者
  • 当您使用按位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
    }
}

答案 1 :(得分:2)

此函数允许您遍历单词中的所有设置位:

inline size_t next_bit(uint64_t bf, size_t bit) {
    return ctz(bf & ~((1UL << bit) -1));
}

ctz函数计算编译器应作为内置函数提供的尾随零的数量。对于gcc和llvm,您可以使用以下内容(请注意,x86上的ctz未定义0因此修复了):

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.

该功能通过清除i位之前的所有位并计算尾随零的数量来工作,这将为您提供i位之后的下一个设置位。通过首先将位移位到i位置,减去将所有位设置为低于i位的位来完成清除位。然后,我们可以NOT掩码获取i之后的所有位,以便AND op将删除i之后的所有位。剩下的就是ctz

对于一个未签名的字符有点过分(双关语),但我无法抗拒。老实说,对于8位字,你可以使用其他答案中提出的简单while循环来改善。

答案 2 :(得分:0)

好吧,从最低位到最高位,你可以这样循环:

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个循环时停止)等等。需要更多上下文来解决具体问题。问题而不是一般循环。 Many specific problems are most efficiently solved with clever bit twiddling hacks.

答案 3 :(得分:0)

#define BIT(a,b)    (a & (1<<b))

void printBits(unsigned char c){
    int i;

    char bits[9];
    for( i=0;i<8;i++){
        bits[i]=BIT(c,i)?'1':'0';

    }
    bits[8]=0;
    char *fmt=isalpha(c)
            ?"'%c'\t= '%s'\n"
            :" %d\t= '%s'\n";
    printf(fmt,c,bits);
}


int main(){


    printBits('A');
    printBits('B');
    printBits(1);
    printBits(2);
    printBits(3);
    return 0;
}

答案 4 :(得分:-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 (" ");
}

}

如果您不理解此代码,请评论,我是24x7在线为您服务。