如何测试是否所有位都已设置或所有位都未设置

How can I test if all bits are set or all bits are not?

本文关键字:设置 何测试 是否 测试      更新时间:2023-10-16

使用逐位运算符如何测试整数的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)。我想找到一种在没有||运算符的情况下在单个测试中实现这一点的方法。

使用逐位运算符,我如何测试整数的n个最低有效位是全集还是全非集。

要获得最后一个n有效位的掩码,即

(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;
}

如果您想避免||,我们将不得不利用整数溢出。对于我们想要的情况,在&之后,val0或(假设n=8)0xff。所以val - 10xffffffffffffffff或者0xfe。故障原因是10xfe,它们变为00xfd。因此,成功案例至少调用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);
}

我们也可以通过加1而不是减1来进行测试,这可能是最好的解决方案(这里,一旦我们向val加1,对于我们的成功案例,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;
}     

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

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

怎么样?

int mask = (1<<n)-1;
if ((x&mask)==mask || (x&mask)==0) { /*do whatever*/ }

唯一真正棘手的部分是掩码的计算。它基本上只是将1移到0b0...0100...0上,然后减去1使其成为0b0...0011...1

也许你可以澄清一下你想要测试什么?

以下是您想要在一个函数中执行的操作(未经测试,但您应该了解这个想法)。如果最后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;
}

要测试是否全部都未设置,只需要屏蔽所需的位,然后只需要与零进行比较。

当你通过反转输入来定义opsite函数时,乐趣就开始了:)

//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);    
}