首页 > 解决方案 > 是比特集吗?仅当编写为 Oneliner 时,函数才返回错误结果

问题描述

对于测试某个位是否设置为无符号整数(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 平台编译的,由于字长或编译器行为,这可能很重要。

标签: c++

解决方案


原来我找到了答案。我遇到了运算符优先级的问题。做的时候

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

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

然后(((unsigned int)1) << bit) & 1被评估,给出1if bit=0,或0在其他情况下。然后该值再次隐式转换为 bool 以返回。

所以问题是没有警告地考虑运算符优先级和隐式转换。逐步运行函数,优先级没有问题,因为比较总是在按位与之后进行。

Oneliner 可以使用附加支架进行固定:

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

推荐阅读