简体   繁体   English

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

[英]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 . 对于我们想要的情况,在&val0或(假设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 . 失败原因是10xfe ,它变为00xfd 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对于我们的成功案例应该变为01 ):

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM