【问题标题】:Extracting bits using bit manipulation使用位操作提取位
【发布时间】:2011-11-18 15:40:17
【问题描述】:

我有一个 32 位无符号整数,我需要在给定位置提取位并从这些位中生成一个新数字。例如,如果我有一个 0xFFFFFFFF 并且想要位 0、10、11,我的结果将是 7 (111b)。

这是我的尝试,它正确提取了位,但没有创建正确的结果。我将结果向左移动 1 位并与我提取的位进行与运算,但显然这是不正确的?

我也确定可能有更优雅的方式来做到这一点?

#define TEST 0xFFFFFFFF

unsigned int extractBits(unsigned short positions[], unsigned short count, unsigned int bytes)
{
    unsigned int result = 0;
    unsigned int bitmask = 0;
    unsigned short bit = 0;
    int i = 0;

    for(i = 0; i < count; i++) {
        bitmask = 2 << (positions[i] -1);
        if(bitmask == 0) bitmask = 1;

        bit = bytes & bitmask;
        bit = bit >> positions[i];

        result = result << 1;
        result = result & bit;  
    }

    if(result != 31) {
        printf("FAIL");
    }

    return result;
}

int main(void)
{
    unsigned short positions[5] = {8, 6, 4, 2, 0};
    unsigned int result = extractBits(positions, 5, TEST);

    printf("Result: %d\n", result);

    return 0;
}

【问题讨论】:

  • 2 &lt;&lt; (positions[i] -1) 应该是 1 &lt;&lt; positions[i]。以负数移动是不行的。

标签: c bit-manipulation


【解决方案1】:

当心,未经测试的代码:

for(i = 0; i < count; i++) 
{
    bitmask = 1 << positions[i];
    bit = (bytes & bitmask)!=0;
    result = (result << 1)|bit;
}

【讨论】:

    【解决方案2】:

    由于您选择的是单个位,因此没有理由将位掩码设为变量;只需将所需的位移入单位位,并使用掩码 1。例如:

    ...
    result = (2*result) | ((bytes >> positions[i]) & 1);
    ...
    

    许多编译器为2*resultresult&lt;&lt;1 生成相同的代码,因此请随意使用。

    请注意,如果您正在设计界面并且没有充分的理由为 positions[]count 使用 short 整数,那么不要这样做。保持一致并以相同的方式指定所有整数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 2020-02-06
      • 2016-12-14
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      相关资源
      最近更新 更多