IsBitSet?仅当编写为Oneliner时,函数才返回错误结果

时间:2018-07-05 14:39:15

标签: c++

对于测试是否在无符号int(16位)值中设置了某个位的函数的行为,我感到很沮丧。

我正在测试电话号码:57393(1110 0000 0011 0001)

无效功能是

bool IsBitSet(int bit, unsigned int value)
{
    return (((unsigned int)1) << bit) & value > 0;
}

测试bit = 0; bit < 7; bit++的功能,我得到结果:1 0 0 0 0 0显然是不正确的。

然后我将函数重写为各个步骤:

bool IsBitSet(int bit, unsigned int value)
{
    unsigned int test = ((unsigned int)1) << bit;
    test = test & value;
    if (test > 0) {
        return true;
    }
    else {
        return false;
    }
}

我认为这应该完全一样。但是,现在我得到正确的输出:1 0 0 0 1 1

由于很少有C ++的经验,我无法弄清楚这两个函数之间的区别是什么。我可以保留更长的功能,但我想了解我哪里出了问题,以免再次遇到此问题。

该代码是为Arduino平台编译的,由于字长或编译器行为,这可能很重要。

2 个答案:

答案 0 :(得分:4)

结果我找到了答案。我遇到了运算符优先级的问题。

(((unsigned int)1) << bit) & value > 0

大于运算符>优先于按位与运算符&,因此value > 0首先被评估为bool true,它隐式转换为1。

然后对(((unsigned int)1) << bit) & 1求值,如果1给出bit=0,在其他情况下给出0。然后,该值再次隐式转换为bool以返回。

因此,问题在于没有考虑运算符优先级并结合了隐式强制转换而没有警告。逐步运行该函数的优先级没有问题,因为比较总是在按位与之后进行。

可以使用其他支架固定Oneliner:

return ((((unsigned int)1) << bit) & value) > 0;

答案 1 :(得分:2)

尽管您的回答是正确的,但是通过删除不必要的括号,您可以获得很多可读性:
return ((((unsigned int)1) << bit) & value) > 0;等效于:
return (1U << bit) & value;