获取 C++ 中的位偏移量

发布于 2024-12-24 02:36:43 字数 126 浏览 2 评论 0原文

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

九厘米的零° 2024-12-31 02:36:43

您在这里有多个答案: 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的幂,查找表可能是最简单和最快的

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

享受孤独 2024-12-31 02:36:43

这是一个对于 32 位值最多只进行五次迭代的版本,与 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;
}

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;
}
浅浅淡淡 2024-12-31 02:36:43

您需要做的就是每次循环并移动一点。但有一种更快的方法使用 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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文