如何测试所有位是否置位或所有位都不是?

Mat*_*agé 8 c c++ bit-manipulation

使用按位运算符如何测试整数的n个最低有效位是全部还是全部未设置.

例如,if n = 3我只关心3个最低有效位,测试应该为0和7返回true,对于0到7之间的所有其他值都为false.

我当然可以这样做if x = 0 or x = 7,但我更喜欢使用按位运算符.

如果可以调整技术以考虑掩码定义的所有位,则奖励点.

澄清:

如果我想测试是否设置了第一或第二位,我可以if ((x & 1 != 0) && (x & 2 != 0)).但我可以做到"更有效率" if ((x & 3) != 0).

我试图找到一个这样的"黑客"来回答这个问题"是否所有匹配此掩码的x都设置了或者都未设置?"

简单的方法是if ((x & mask) == 0 || (x & mask) == mask).我想在没有||的单个测试中找到一种方法 运营商.

Bar*_*rry 10

使用按位运算符如何测试整数的n个最低有效位是全部还是全部未设置.

为了获得最后一个n有效位的掩码,那就是

(1ULL << n) - 1
Run Code Online (Sandbox Code Playgroud)

所以简单的测试是:

bool test_all_or_none(uint64_t val, uint64_t n)
{
    uint64_t mask = (1ULL << n) - 1;
    val &= mask;
    return val == mask || val == 0;
}
Run Code Online (Sandbox Code Playgroud)

如果你想避免||,我们将不得不利用整数溢出.对于我们想要的情况,在之后&,val或者是0(或者说n == 8)0xff.所以val - 10xffffffffffffffff或者0xfe.失败的原因是1通过0xfe,0通过0xfd.因此成功案例至少是召唤0xfe,即mask - 1:

bool test_all_or_none(uint64_t val, uint64_t n)
{
    uint64_t mask = (1ULL << n) - 1;
    val &= mask;
    return (val - 1) >= (mask - 1);
}
Run Code Online (Sandbox Code Playgroud)

我们也可以通过添加1而不是减去1进行测试,这可能是最好的解决方案(这里我们添加一个val,val & mask应该成为0或者1对于我们的成功案例):

bool test_all_or_none(uint64_t val, uint64_t n)
{
    uint64_t mask = (1ULL << n) - 1;
    return ((val + 1) & mask) <= 1;
}     
Run Code Online (Sandbox Code Playgroud)

对于任意掩码,减法方法的工作原理与它对特定掩码大小写相同:将0翻转作为最大可能值:

bool test_all_or_none(uint64_t val, uint64_t mask)
{
    return ((val & mask) - 1) >= (mask - 1);
}
Run Code Online (Sandbox Code Playgroud)