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 - 1是0xffffffffffffffff或者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)