如何测试所有位是否都置位? [英] How can I test if all bits are set or all bits are not?

查看:42
本文介绍了如何测试所有位是否都置位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 = 3 ,我只关心3个最低有效位,则测试应针对0和7返回true,而对于其他介于0和7之间的其他值,则返回false.

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.

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

Of course I could do if x = 0 or x = 7, but I would prefer something using bitwise operators.

奖励指出该技术是否可以适用于考虑由掩码定义的所有位.

Bonus points if the technique can be adapted to take into accounts all the bits defined by a mask.

说明:

如果我想测试是否设置了第1位或第2位,则可以使用 if((x& 1!= 0)&&(x& 2!= 0)).但是我可以做更高效"的 if((x& 3)!= 0).

If I wanted to test if bit one or two is set I could to if ((x & 1 != 0) && (x & 2 != 0)). But I could do the "more efficient" if ((x & 3) != 0).

我正试图找到一个像这样的"hack"来回答问题与该掩码匹配的x的所有位是否全部置位或全部未置位?"

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?"

简单的方法是 if((x& mask)== 0 ||(x& mask)== mask).我想找到一种方法在没有||的情况下进行单个测试运算符.

The easy way is if ((x & mask) == 0 || (x & mask) == mask). I'd like to find a way to do this in a single test without the || operator.

推荐答案

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

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

(1ULL << n) - 1

所以简单的测试是:

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

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

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. So val - 1 is either 0xffffffffffffffff or 0xfe. The failure causes are 1 thru 0xfe, which become 0 through 0xfd. Thus the success cases are call at least 0xfe, which is 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);
}

我们还可以通过加1而不是减1进行测试,这可能是最好的解决方案(在这里,一旦我们将 val 加一个, val& mask 应该变成对于我们的成功案例,为 0 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):

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

对于任意掩码,减法的工作原理与在特定掩码情况下起作用的原因相同: 0 翻转为最大可能值:

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:

bool test_all_or_none(uint64_t val, uint64_t mask)
{
    return ((val & mask) - 1) >= (mask - 1);
}

这篇关于如何测试所有位是否都置位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆