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.
CodePudding user response:
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. Ifx
is0
, 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!
CodePudding user response:
Shift one bit at a time until its in the low position and increment a counter each time.
int get_bit_num(uint32_t n)
{
int count = 0;
while (n>1) {
n >>= 1;
count ;
}
return count;
}