Enum bits to index

Started by
3 comments, last by alvaro 13 years, 5 months ago
Say I have an enum of bits

#define BIT(n) (1 << (n))enum MyEnum{    MYENUM_NONE = 0,    MYENUM_ONE = BIT(0),    MYENUM_TWO = BIT(1),    MYENUM_THREE = BIT(2)    ...};


Is there a simple way to convert their values to indexes in the enum?

Eg.

MYENUM_NONE to 0, MYENUM_ONE to 1, MYENUM_TWO to 2 and MYENUM_THREE to 3 and so on. I understand I could do this in a for loop and test each bit, but I want a single statement like a bitshift or something.
Advertisement
Well, chances are that your processor has a single instruction for this kind of thing. The trick is accessing it. For x86 it's BSR, which you can usually grab with inline assembly, if you consider that to be a single statement. If you're using gcc you can use __builtin_ctz() (count trailing zeros). However, these have unpredictable results when you pass in 0 as an argument. If you're willing to settle for multiple statements that don't involve for loops there are various bithacks you can try. However, most of those are severely obfuscated algorithms.
This operation is very common in computer chess when using the bitboard representation. The fastest method is often what's labeled "Count the consecutive zero bits (trailing) on the right with multiply and lookup" in the page SiCrane linked to.

On POSIX systems (e.g., Linux) you have a function ffs, which does exactly what you want.

I was hoping of a nice single statement in C to do it. Oh well just went with a loop and bit check. Thanks anyway.
Quote:Original post by Headkaze
I was hoping of a nice single statement in C to do it. Oh well just went with a loop and bit check. Thanks anyway.


It can be done with one line, but it's not pretty or fast:
#include <math.h>unsigned ffs(unsigned x) {  return x ? 1 + log(double(x))/log(2.0) : 0;}

This topic is closed to new replies.

Advertisement