将2位掩码的幂转换为相应的索引

发布于 2025-01-15 09:34:37 字数 592 浏览 3 评论 0原文

我一直在寻找这个问题的答案,但没有找到任何合适的解决方案。我正在尝试将单个启用位(32 位掩码)转换为其相应的索引位置。该掩码仅启用了一位,从位 0 到位 31。

因此,这是我正在寻找的转换: 1=1、2=2、4=3、8=4、16=5、32=6 等等。

我不反对创建一个查找表,如果该表不是很大而且大部分是空的。是否有任何聪明的数学可以一步完成这一任务(无需循环遍历这些位)?

编辑:我在提供的链接中找不到满意的答案。但在闲逛了一些数字之后,我确实偶然发现了一个神奇的值,它可以完美地分离 32 位掩码的两个值的幂。该值为 37。如果您将任何 32 位 2 的幂值调制为 37,它将将该 2 的幂值转换为 1 - 36 之间的索引。这意味着我们可以创建一个包含 37 个值的小型查找表,仅浪费了一些条目。这是该表的填充率: |0|1|1|1|1|1|1|0|1|1|1|1|1|1|0|1|1|1|1|0|1|1|1|1|1 |1|1|1|0|1|1|1|1|1|1|1|1|

我将进一步尝试一下,看看 64 位值是否可以实现这样的事情。

我不明白为什么这个论坛这么快就结束话题了。这使得不可能对以前讨论过的事情进行任何类型的讨论。

I've been looking around for an answer to this, but haven't found any decent solutions. I'm trying to convert a single-enabled-bit (32-bit mask) into its corresponding index location. The mask has only one bit enabled, from bit 0 to bit 31.

So here are the conversions I'm looking for:
1=1, 2=2, 4=3, 8=4, 16=5, 32=6, etc..

I'm not against making a lookup table, if the table isn't both terribly large and mostly empty. Is there any clever math out there to accomplish this in one step (without looping through the bits)?

EDIT: I could not find a satisfactory answer in the link provided. But after goofing around with some numbers, I did stumble onto a magic value that separates power of two values perfectly for 32 bit masks. That value is 37. If you modulate any 32-bit power of 2 value by 37, it will convert that power of two value into an index between 1 - 36. This means we can create a tiny lookup table of 37 values, with only a few entries wasted. Here is the fill rate of that table:
|0|1|1|1|1|1|1|0|1|1|1|1|1|1|0|1|1|1|1|0|1|1|1|1|1|1|1|1|0|1|1|1|1|1|1|1|1|

I will mess around a little more to see if such a thing is possible with 64 bit values.

I don't understand why this forum is so quick to close topics. It makes it impossible to have any type of discussion about something that has been discussed before.

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

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

发布评论

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

评论(2

_失温 2025-01-22 09:34:37

这是一个受 Bit Twiddling Hacks 启发的解决方案:

  • 首先将值递减为将索引下面的所有位设置为 1
  • ,然后计算结果值中的位数,
  • 添加 1 以获得预期结果
int bit_index(uint32_t v) {
    v -= 1;
    v = v - ((v >> 1) & 0x55555555);                // reuse input as temporary
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
    return 1 + (((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); // count
}

Here is a solution inspired from Bit Twiddling Hacks:

  • first decrement the value to set all bits below the index to 1
  • then count the number of bit in the resulting value
  • add 1 to get the expected result
int bit_index(uint32_t v) {
    v -= 1;
    v = v - ((v >> 1) & 0x55555555);                // reuse input as temporary
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
    return 1 + (((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); // count
}
烧了回忆取暖 2025-01-22 09:34:37

只需将位向右移动,直到全部为零:

#include <stdio.h>

int main(void)
{
    int n, pos, x;

    n = scanf("%d", &x);
    if (n == 1) {
        pos = 0;
        while (x != 0) {
            x >>= 1;
            pos++;
        }
        printf("%d\n", pos);
    }
    return 0;
}

Simply shift the bits to the right until all are zero:

#include <stdio.h>

int main(void)
{
    int n, pos, x;

    n = scanf("%d", &x);
    if (n == 1) {
        pos = 0;
        while (x != 0) {
            x >>= 1;
            pos++;
        }
        printf("%d\n", pos);
    }
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文