Looping through Bits C

只愿长相守 提交于 2019-12-07 22:44:25

问题


I'm trying to loop through the bits of an unsigned char, but I'm not sure where to start, eventually, I'll perform other bitwise operating on the bits, such as ~ and xor..etc.


回答1:


Looping over bits can be done in several ways:

  • You can do a destructive loop, when you shift the value, and test the initial or the final bit, depending on the order in which you would like to enumerate bits, or
  • You can do a non-destructive loop, when you use bitwise AND to test the number with a single-bit mask, produced by left-shifting 1.

Here is an example of the first approach:

unsigned int bits = ...;
while (bits) {
    if (bits & 1) {
        // Current bit is set to 1
    } else {
        // Current bit is set to 0
    }
    bits >>= 1;
}

If you want to continue working with bits after you reach zero, make a separate counter.

Here is an example of the second approach:

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
    }
}



回答2:


This function will allow you to iterate through all set bits in a word:

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

The ctz function counts the number of trailing zeroes which should be provided by your compiler as a built-in function. For gcc and llvm, you can use the following (note that ctz is undefined for 0 on x86 hence the fixup):

inline size_t ctz(uint64_t x) { return x ? __builtin_ctzll(x) : 64; }

Here's an example of how to use it in a for-loop:

for (size_t i = next_bit(bf, 0); i < 64; i = next_bit(bf, i + 1))
    // the i-th bit is set.

The function works by clearing away all the bits preceding the ith bit and counting the number of trailing zeroes which will provide you with the next set bit after the ith bit. Clearing the bits is accomplished by first shifting a bit into the ith position, subtracting one which sets all the bits lower then the ith bit. We can then NOT the mask to get all the bits after i so that an AND op will remove all the bits after i. ctz does the rest.

It's a bit (pun intended) overkill for an unsigned char but I couldn't resist. Honestly, for 8-bit words, you're better off with a simple while loop as proposed in the other answers.




回答3:


Well, from lowest to highest bit, you can loop like so:

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
    }
}

That's a really general use case though; typically, you want to parallelize your work (operate on a whole byte at a time), or only operate on the 1 bits (and stop when you run out instead of finishing all eight loops), etc. More context is needed to solve specific problems rather than general looping. Many specific problems are most efficiently solved with clever bit twiddling hacks.




回答4:


#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;
}



回答5:


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 (" ");
}

}

If you don't understand this code please comment, I'm 24x7 online for you.



来源:https://stackoverflow.com/questions/33005271/looping-through-bits-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!