Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Get number of sole bit in bitfield

I have a 32-bit bitfield where a single bit is set. How can I get the number of this bit (as int or something)?

Examples (using 8 bit for brevity):

Input              Desired output
0x01 / 00000001 -> 0
0x04 / 00000100 -> 2
0x08 / 00001000 -> 3
0x00 / 00000000 -> undefined/whatever
0x06 / 00000110 -> undefined/whatever

I’m looking for succinct and readable code or common library functions, not for the most clever or best performing solution.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can use a compiler builtin for this. gcc and clang support this:

Built-in Function: int __builtin_clz(unsigned int x)

Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.

int bit_index32(unsigned x) {
    return 31 - __builtin_clz(x);
}

For a more portable solution, you can use a simple loop:

int bit_index32(unsigned x) {
    int n = 0;
    while (x > 1) { n++; x >>= 1; }
    return n;
}

A faster one with just 5 tests instead of up to 31:

int bit_index32(unsigned x) {
    int n = 0;
    if (x > 0xFFFF) { n += 16; x >>= 16; }
    if (x > 0xFF)   { n +=  8; x >>=  8; }
    if (x > 0xF)    { n +=  4; x >>=  4; }
    if (x > 0x3)    { n +=  2; x >>=  2; }
    if (x > 0x1)    { n +=  1; x >>=  1; }
    return n;
}

Since v is a power of 2, the index is the number of bits in v-1, which can be computes without tests:

int bit_index32(unsigned v) {
    v--;
    v = v - ((v >> 1) & 0x55555555);
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
    return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}

Another branchless one that only works for powers of 2:

int bit_index32(unsigned v) {
    return !!(v & 0xAAAAAAAA)
         | !!(v & 0xCCCCCCCC) << 1
         | !!(v & 0xF0F0F0F0) << 2
         | !!(v & 0xFF00FF00) << 3
         | !!(v & 0xFFFF0000) << 4;
}

More fun at Sean Anderson’s Bit Twiddling Hacks!

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading