【问题标题】:Determine which single bit is set in 16 bit variable [duplicate]确定在 16 位变量中设置了哪个单个位 [重复]
【发布时间】:2018-09-18 10:36:23
【问题描述】:

我正在寻找一种算法来确定像 0x200 这样的 16 位 (uint16_t) 变量中的哪一个位(始终只有一个位集)。我发现了一个非常不错的简短有效的代码来使用 8 位变量的查找表来执行此操作,如下所示:

int[] lookup = {7, 0, 5, 1, 6, 4, 3, 2};

int getBitPosition(unsigned char b) {
  return lookup[((b * 0x1D) >> 4) & 0x7];
}

如何扩展它以使用 16 位作为输入?

【问题讨论】:

  • 请注意,这个问题相当于一个数字的 log2,它是 2 的精确幂,或“计数前导零”、“计数尾随零”或“查找第一个设置位”。参见例如this question 及其各种副本。还有this question 及其各种副本。
  • 使用 ffs 或 clz 函数。
  • 数一数。结果必须除以 2 才能得到 0 的次数
  • int[] lookup ==>> int lookup[]
  • @PaulR 请不要建议关闭帖子作为重复,如果需要,之后很难删除已关闭的帖子。此外,在其中混入 log 函数也不是很有帮助,因为它使用浮点数。

标签: c bit-manipulation


【解决方案1】:

怎么样:

int bitset(unsigned short s)
{
    int lookup[] = {16, 1, 11, 2, 14, 12, 3, 6, 15, 10, 13, 5, 9, 4, 8, 7};
    return lookup[(((int) s*0x6F28)>>14)&15];
}

测试:

int main(void)
{
    int i, j;
    for (i = j = 1; i <= 16; ++i, j <<=1)
    {
        printf("for %5d, the %3dth bit is set\n", j, bitset(j));
    }
    return 0;
}

给予:

for     1, the  1th bit is set
for     2, the  2th bit is set
for     4, the  3th bit is set
for     8, the  4th bit is set
for    16, the  5th bit is set
for    32, the  6th bit is set
for    64, the  7th bit is set
for   128, the  8th bit is set
for   256, the  9th bit is set
for   512, the 10th bit is set
for  1024, the 11th bit is set
for  2048, the 12th bit is set
for  4096, the 13th bit is set
for  8192, the 14th bit is set
for 16384, the 15th bit is set
for 32768, the 16th bit is set

说明

第一个算法(8bits)如下:

用两个数字(1、2、4...)的幂构建一个唯一的数字

传入号码s可以按位分解:

s7s6s5s4s3s2s1s0, for instance, s == 4 means s2 = 1, other = 0

一个数字是构建不同 sx 的总和:

这个操作是由*操作完成的(0x1D是11101b)

        |s7s6s5s4|s3s2s1s0    //     1b
    s7s6|s5s4s3s2|s1s0 0 0    //   100b
  s7s6s5|s4s3s2s1|s0 0 0 0    //  1000b
s7s6s5s4|s3s2s1s0| 0 0 0 0    // 10000b

查看管道之间的数字:它是唯一的,

  • 如果s 为1,则和(管道之间)为0b+0b+0b+1b = 1
  • 如果s 为2,则和(管道之间)为0b+0b+1b+10b = 2
  • 如果s 为4,则和(管道之间)为0b+1b+10b+100b = 7
  • 如果s 为8,则和(管道之间)为0b+10b+100b+1000b = 14

等等

&gt;&gt;&amp; 操作选择 4 个中间位。

最后,对唯一编号应用一个简单的查找表以获取设置位。

16 位算法是对此的概括,困难在于找到一个位组合,该组合给出了 2 的幂的唯一数字。

【讨论】:

  • 谢谢!!!!对不起,迟到的答案。如何为您的努力发送优质的德国啤酒。奇妙的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多