[英]How can I test if all bits are set or all bits are not?
Using bitwise operator how can I test if the n least significant bits of an integer are either all sets or all not sets. 使用按位运算符如何测试整数的n个最低有效位是全部还是全部未设置。
For example if n = 3
I only care about the 3 least significant bits the test should return true for 0 and 7 and false for all other values between 0 and 7. 例如,
if n = 3
我只关心3个最低有效位,测试应该为0和7返回true,对0到7之间的所有其他值都返回false。
Of course I could do if x = 0 or x = 7
, but I would prefer something using bitwise operators. 当然,
if x = 0 or x = 7
,我可以做,但我更喜欢使用按位运算符。
Bonus points if the technique can be adapted to take into accounts all the bits defined by a mask. 如果可以调整技术以考虑掩码定义的所有位,则奖励点。
Clarification : 澄清:
If I wanted to test if bit one or two is set I could to if ((x & 1 != 0) && (x & 2 != 0))
. 如果我想测试是否设置了第一或第二位,我可以去
if ((x & 1 != 0) && (x & 2 != 0))
。 But I could do the "more efficient" if ((x & 3) != 0)
. 但是
if ((x & 3) != 0)
我可以做“更有效”。
I'm trying to find a "hack" like this to answer the question "Are all bits of x that match this mask all set or all unset?" 我试图找到一个这样的“黑客”来回答这个问题“是否所有匹配此掩码的x都设置了或者都未设置?”
The easy way is if ((x & mask) == 0 || (x & mask) == mask)
. 简单的方法是
if ((x & mask) == 0 || (x & mask) == mask)
。 I'd like to find a way to do this in a single test without the || 我想在没有||的单个测试中找到一种方法 operator.
运营商。
Using bitwise operator how can I test if the n least significant bits of an integer are either all sets or all not sets.
使用按位运算符如何测试整数的n个最低有效位是全部还是全部未设置。
To get a mask for the last n
significant bits, thats 要获得最后
n
有效位的掩码,那就是
(1ULL << n) - 1
So the simple test is: 所以简单的测试是:
bool test_all_or_none(uint64_t val, uint64_t n)
{
uint64_t mask = (1ULL << n) - 1;
val &= mask;
return val == mask || val == 0;
}
If you want to avoid the ||
如果你想避免
||
, we'll have to take advantage of integer overflow. ,我们将不得不利用整数溢出。 For the cases we want, after the
&
, val
is either 0
or (let's say n == 8) 0xff
. 对于我们想要的情况,在
&
, val
为0
或(假设n == 8) 0xff
。 So val - 1
is either 0xffffffffffffffff
or 0xfe
. 所以
val - 1
要么是0xffffffffffffffff
要么是0xfe
。 The failure causes are 1
thru 0xfe
, which become 0
through 0xfd
. 失败原因是
1
到0xfe
,它变为0
到0xfd
。 Thus the success cases are call at least 0xfe
, which is mask - 1
: 因此,成功案例至少调用
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);
}
We can also test by adding 1 instead of subtracting 1, which is probably the best solution (here once we add one to val
, val & mask
should become either 0
or 1
for our success cases): 我们也可以通过添加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;
}
For an arbitrary mask, the subtraction method works for the same reason that it worked for the specific mask case: the 0
flips to be the largest possible value: 对于任意掩码,减法方法的工作原理与它对特定掩码大小写相同:
0
翻转为最大可能值:
bool test_all_or_none(uint64_t val, uint64_t mask)
{
return ((val & mask) - 1) >= (mask - 1);
}
How about? 怎么样?
int mask = (1<<n)-1;
if ((x&mask)==mask || (x&mask)==0) { /*do whatever*/ }
The only really tricky part is the calculation of the mask. 唯一真正棘手的部分是掩模的计算。 It basically just shifts a 1 over to get
0b0...0100...0
and then subtracts one to make it 0b0...0011...1
. 它基本上只是将1移位到
0b0...0100...0
然后减去一个使其成为0b0...0011...1
。
Maybe you can clarify what you wanted for the test? 也许你可以澄清你想要的测试?
Here's what you wanted to do, in one function (untested, but you should get the idea). 这是你想要做的,在一个功能中(未经测试,但你应该得到这个想法)。 Returns 0 if the n last bits are not set, 1 if they are all set, -1 otherwise.
如果未设置n个最后一位,则返回0;如果全部设置则返回1,否则返回-1。
int lastBitsSet(int num, int n){
int mask = (1 << n) - 1; //n 1-s
if (!(num & mask)) //we got all 0-s
return 0;
if (!(~num & mask)) //we got all 1-s
return 1;
else
return -1;
}
To test if all aren't set, you just need to mask-in only the bits you want, then you just need to compare to zero. 要测试是否所有都未设置,您只需要屏蔽所需的位,然后您只需要比较为零。
The fun starts when you define the oposite function by just inverting the input :) 当您通过反转输入来定义oposite函数时,乐趣开始了:)
//Test if the n least significant bits arent set:
char n_least_arent_set(unsigned int n, unsigned int value){
unsigned int mask = pow(2, n) - 1; // e. g. 2^3 - 1 = b111
int masked_value = value & mask;
return masked_value == 0; // if all are zero, the mask operation returns a full-zero.
}
//test if the n least significant bits are set:
char n_least_are_set(unsigned int n, unsigned int value){
unsigned int rev_value = ~value;
return n_least_arent_set(n, rev_value);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.