【问题标题】:What are the ways to extract 8 nibbles in an integer (assuming 32bit integer) in C?在C中提取整数(假设为32位整数)中的8个半字节的方法是什么?
【发布时间】:2012-08-30 07:00:28
【问题描述】:

我正在尝试一个基本的哈希表程序..它是在一个整数中计算 1 的个数:

我有一个哈希表,它是一个数组,在0,1,2...E,F 中有一个 1 的个数

HashTable:
0   0
1   1
2   1
3   2
4   1
5   1
6   2
7   3
8   1
9   2
A   2
B   3
C   2
D   3
E   3
F   4

现在,我想从整数中提取 8 个半字节,以便我可以使用 arr[nibble-value] 来获取每个半字节中 1 的数量。

int arr[16] = {0,1,1,2,1,1,2,3,1,2,2,3,2,3,3,4};

int main (void)  
{
    int x = 127;
    int temp, sum =0, i;
    int nibbles = 2 * sizeof(x);
    for (i = 1; i<= nibbles; i++) 
    {
        temp = x << (4*i);   //  <<< I Know this is wrong!!!! <<Here is what I need!!>>
        printf("Temp[%d]:%d\n", i, temp);
        sum = sum + arr[temp];
    }
    printf("No.of ones: %d\n", sum);
    return 0;
}

可能是一个简单的逻辑......

【问题讨论】:

  • 顺便说一句,你的最终目标是:获得每个半字节设置的总位数吗?
  • 我只是在尝试基本的哈希表技术,所以来回答你的问题..是的!
  • 顺便说一句,设置的位数称为“人口计数”或“人口计数”。有了这个搜索词,您可以找到很多关于其他方法的信息,如果您有兴趣的话。

标签: c bitwise-operators bit-shift


【解决方案1】:

请记住,第一位编号为零,第一个半字节也是如此,就像数组索引一样。因此,通过从1 开始循环,您实际上是从 second 半字节开始,并从 整数中获取最后一个半字节。

另外,你换错了方向,应该屏蔽掉最高位,即做

for (i = 0; i< nibbles; i++) 
{
    temp = (x >> (4 * i)) & 0x0f;
    /* ... */
}

【讨论】:

    【解决方案2】:

    变化就在这一行:temp = 0xF &amp; (x &gt;&gt; i*4);

    #include <stdio.h>
    
    int arr[16] = {0,1,1,2,1,1,2,3,1,2,2,3,2,3,3,4};
    
    int main (void)  
    {
         int x = 127;
         int temp, sum =0, i;
         int nibbles = 2 * sizeof(x);
         for (i = 0; i<nibbles; i++) 
         {
             temp = 0xF & (x >> i*4); // I Know this is wrong!!!! <<Here is what I need!!>>
             printf("Temp[%d]:%d\n", i, temp);
             sum = sum + arr[temp];
         }
         printf("No.of ones: %d\n", sum);
         return 0;
    }   
    

    【讨论】:

      【解决方案3】:

      有时,修改现有状态并在循环体中做更少(看似)工作会更容易:

      for (i = 0; i < nibbles; i++, x >>= 4) 
      {
          temp = x & 0xf;
          /* ... */
      }
      

      上面在每次循环迭代中修改x,所以要提取下一个半字节,我们只需要在每次迭代中获取四个最低有效位。这消除了半复杂的半字节掩码表达式,这可能被认为使代码更易于阅读。

      【讨论】:

        【解决方案4】:

        我觉得你需要

        for (i = 0; i<8; i++) 
        {
        
             temp = (x>>(i*4)) & 0xF;
             printf("Temp[%d]:%d\n", i, temp);
             sum += arr[temp];
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-07
          • 2018-05-15
          • 1970-01-01
          • 2011-09-26
          • 2014-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多