I have an int
parameter with the possible values 1,2,4,8,16,32,64.
I need to know the bit offset of the current value, i.e. for each value return 1, 2, 3, 4, 5, or 6 respectively.
What is the easiest way to achieve that?
I have an int
parameter with the possible values 1,2,4,8,16,32,64.
I need to know the bit offset of the current value, i.e. for each value return 1, 2, 3, 4, 5, or 6 respectively.
What is the easiest way to achieve that?
You have multiple answers here : http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious the easiest being, assuming you have your input value in an unsigned int v :
unsigned int r = 0; // r will be lg(v)
while (v >>= 1) // unroll for more speed...
{
r++;
}
but it will change v in the process.
edit: in your case if you are 100% sure your input is and int and a power of 2, a look-up-table may be the simplest and fastest
Here's a version that only does five iterations at most for a 32 bit value, unlike lezebulon's answer which has a worst case of 32 iterations. Adapting to 64 bit values increases the iteration count of this version to six and the other to 64 at worst.
int get_pos (unsigned v)
{
int s=16,p=0,m=0xffff;
while (s)
{
if (v>>s) p += s;
v = (v | (v >> s)) & m;
s >>= 1;
m >>= s;
}
return p;
}
All you need to do is loop and shift a bit each time. But there's a faster way using switch case. listing both for you.
//more code but awesomely fast
int getBitOffset1(int d) {
switch(d) {
case 1: return 1;
case 2: return 2;
case 4: return 3;
case 8: return 4;
case 16: return 5;
case 32: return 6;
/* keep adding case upto sizeof int*8 */
}
}
//less code, the loop goes 64 times max
int getBitOffset2(int d) {
int seed=0x01;
int retval=0;
do{
if(seed<<retval == d) {
break;
}
retval++;
}while(retval<=sizeof(int)*8);
return retval+1;
}
int main() {
printf("%d\n", getBitOffset2(32));
printf("%d\n", getBitOffset2(1));
return 0;
}