简体   繁体   English

在C ++中获取位偏移

[英]Get bit offset in C++

I have an int parameter with the possible values 1,2,4,8,16,32,64. 我有一个int参数,可能的值为1,2,4,8,16,32,64。

I need to know the bit offset of the current value, ie for each value return 1, 2, 3, 4, 5, or 6 respectively. 我需要知道当前值的位偏移量,即每个值分别返回1、2、3、4、5或6。

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 : 您在这里有多个答案: http : //graphics.stanford.edu/~seander/bithacks.html#IntegerLog很简单,假设您的输入值是无符号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. 但它将在此过程中更改v。

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 编辑:在您的情况下,如果您100%确定输入为int且乘方为2,则查找表可能是最简单,最快的

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. 这是一个版本,最多只对32位值执行五次迭代,这与lezebulon的答案不同,后者的最坏情况是32次迭代。 Adapting to 64 bit values increases the iteration count of this version to six and the other to 64 at worst. 适应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;
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM