Sign in to follow this  

Enum bits to index

Recommended Posts

Say I have an enum of bits

#define BIT(n) (1 << (n))

enum MyEnum

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


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.

Share this post

Link to post
Share on other sites
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.

Share this post

Link to post
Share on other sites
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.

Share this post

Link to post
Share on other sites
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;

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this