在C ++中获取位偏移量

时间:2012-01-04 15:11:58

标签: c++ bit-manipulation offset

我有int参数,可能的值为1,2,4,8,16,32,64。

我需要知道当前值的位偏移,即每个值分别返回1,2,3,4,5或6。

实现这一目标的最简单方法是什么?

3 个答案:

答案 0 :(得分:4)

您在这里有多个答案:http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious 假设你的输入值是unsigned int v:

,这是最容易的
unsigned int r = 0; // r will be lg(v)

while (v >>= 1) // unroll for more speed...
{
  r++;
}

但它会在此过程中改变v。

编辑:在你的情况下,如果你100%确定你的输入是和int和2的幂,查找表可能是最简单和最快的

答案 1 :(得分:1)

这是一个版本,对于32位值最多只能进行5次迭代,这与lezebulon的答案不同,后者最糟糕的情况是32次迭代。适应64位值会使此版本的迭代次数增加到6次,而另一次则增加到64次。

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;
}

答案 2 :(得分:0)

您需要做的就是每次循环和移位。但是使用switch case有一种更快的方法。列出这两个。

//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;
}