为什么此位计数代码未通过其测试?

时间:2018-09-18 10:49:08

标签: c bit

我现在正在进行bit.c实验,并创建了bitCount函数,我认为它很完美,但无法通过测试。我不知道为什么。

int bitCount(int x) {
    unsigned int a = 0x01010101;
    int b;
    int result = 0;
    result += a&x;
    result += a&(x>>1);
    result += a&(x>>2);
    result += a&(x>>3);
    result += a&(x>>4);
    result += a&(x>>5);
    result += a&(x>>6);
    result += a&(x>>7);
    b = result + result >> 8;
    b = b + result >> 16;
    b = b + result >> 24;
    return b&0xff;
}

1 个答案:

答案 0 :(得分:3)

在这些行中,由于+的优先级高于>>,因此您正在对错误的位求和:

b = result + result >> 8;
b = b + result >> 16;
b = b + result >> 24;

我们假设result == 0x01020304

  • 表达式result + result >> 8的结果为0x01020304 + 0x01020304 >> 8,然后为0x02040608 >> 8,最后为0x020406
  • 表达式b = b + result >> 16的结果为0x020406 + 0x01020304 >> 16,然后为0x0104070A >> 16,最后为0x010407
  • 表达式b = b + result >> 24的结果为0x010407 + 0x01020304 >> 24,然后为0x0103070B >> 24,最后为0x010307
  • 最后,表达式b&0xff产生0x07。不是我们预期的结果0x0A或10。

因此您必须:

  1. 确保在添加之前已完成转换。使用括号()
  2. & 0xFF屏蔽掉不必要的位。请注意,由于存在b&0xff,因此这并不是严格必要的,但我认为这样做可以使意图更清晰。

示例:

b = (result & 0xFF) + (result >> 8 & 0xFF);
b = b + (result >> 16 & 0xFF);
b = b + (result >> 24 & 0xFF);