Reputation: 23
What is a good bit-twiddling routine to convert a number in the range [2^N,2^(N-1)-1] to N?
Some examples:
Here is one implementation:
uint f(uint num)
{
for (uint shifts = 0; num; shifts++)
num >>= 1;
return (shifts - 1);
}
Upvotes: 2
Views: 292
Reputation: 3888
As most general approach, binary search may help. For values 0..31 it need only 5 stages.
y = 0;
if(x >= 0x10000<<y) y += 0x10;
if(x >= 0x100<<y) y += 0x08;
if(x >= 0x10<<y) y += 0x04;
if(x >= 0x4<<y) y += 0x02;
if(x >= 0x2<<y) y += 0x01;
Upvotes: 3
Reputation: 14880
Take a look at hacks for computing base 2 logarithm (or leading zero count, they are the same) on this page: http://www-graphics.stanford.edu/~seander/bithacks.html
You could also find useful the function __builtin_clz
(or _BitScanReverse
for VS) for x86.
Upvotes: 1
Reputation: 272517
Depending on how wide your data-type is, and how much memory you have available, a lookup-table is one possibility. It's almost certainly the fastest approach.
For other approaches, see http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious, and the subsequent sections.
Upvotes: 4