You should check this suggestion (and any others given here) against your current code - you may find that the bitshifting is the most efficient way, or that the difference is minuscule in which case you should optimise for readability.
In any case, consider this something to try and benchmark rather than something that's guaranteed to be faster.
Since there are only 64 possible values, you can just use something like:
int getSetBit (unsigned long x) {
if (x == 0x8000000000000000UL) return 63;
if (x == 0x4000000000000000UL) return 62;
if (x == 0x2000000000000000UL) return 61;
if (x == 0x1000000000000000UL) return 60;
if (x == 0x0800000000000000UL) return 59;
if (x == 0x0400000000000000UL) return 58;
:
if (x == 0x0000000000000002UL) return 1;
return 0;
}
You may find that's faster but solutions will generally be affected by a whole lot of things outside the scope of the standard (optimisation strategies, data caching, pipelining and so forth).
If you're willing to move away from Standard C, many environments will have optimised things you can use, such as the gcc
:
int __builtin_ffs (unsigned int x)
// Returns one plus the index of the least significant
// 1-bit of x, or if x is zero, returns zero.
Of course, with that one, you may have to split the long
into two int
types and check each one individually, something like (untested but you should get the general idea):
if (x < 0x80000000UL) return __builtin_ffs((unsigned int)x) - 1;
return __builtin_ffs((unsigned int)(x>>32)) -1 + 32;
Alternatively, the output from __builtin_clzl()
can be manipulated to give you the bit position (it gives you the leading zero count) and it works with unsigned long
already. You can see the gcc
built-ins here.