如何检查最后四位(LSB)中至少有三个是否打开

时间:2010-01-13 03:18:37

标签: c

我尝试在C中执行此操作:

    int val = 0xCAFE;
int uc = val & 14;


if (val & 15 == 15 || val & 7 == 7 || val & 11 == 11|| val & 13 == 13 || val & 14 == 14){
    printf("asdjfkadscjas \n");
}

然而,这不是应该打印随机字符串。它适用于15,7,11,13 tho。

如果有人知道更好的方式会有所帮助。我对bitwise运算符很不好。

由于

12 个答案:

答案 0 :(得分:21)

替代解决方案:您可以将所有数字放入二进制编码的查找表中:

int AtleastThreeBits (int a)
{
  return (0xe880>>(a&15))&1;
}

幻数的每一位代表一个答案。在常数0xe880位中设置7,11,13,14和15。使用shift选择正确的位并将其屏蔽掉。

它不像你的解决方案那么可读但更快......

答案 1 :(得分:6)

您遇到操作员优先级问题,而不是操作问题。 ==的优先级高于&

if ((val & 15) == 15 || (val & 7) == 7 || ...

此外,您无需检查15。

答案 2 :(得分:6)

if (((value & 1 ? 1 : 0) +
     (value & 2 ? 1 : 0) +
     (value & 4 ? 1 : 0) +
     (value & 8 ? 1 : 0)) >=3)

答案 3 :(得分:2)

比较运算符优先于按位运算符,因此将parens放在&运算符周围。操作者:

if( (val & 15) == 15 || (val & 14) == 14 || ... ) {
    printf( "random string...\n" );
}

答案 4 :(得分:2)

你可以尝试一下查找表!然后你可以轻松改变你的门槛。

static int nibbleCounts[] = { 0, 1, 1, 2,
                              1, 2, 2, 3,
                              1, 2, 2, 3,
                              2, 3, 3, 4 };
if (nibbleCounts[value & 0xF] >= 3)
    puts ("Hello!");

答案 5 :(得分:2)

您可以使用附加的进位来“填写”数字中的第1个0位“孔”。我们在底部半字节中最多允许其中一个,因此将原始值和“填充”版本与|组合将产生一个底部半字节,在这种情况下所有1位:

if (((val | (val + 1)) & 15) == 15)

我认为到目前为止,任何(无查找表)解决方案的操作都是最少的 - 不,实际上Nils Pipenbrinck's clever "in-place lookup table"甚至更少!

答案 6 :(得分:1)

一种简单的方法,也可以清楚地表明你的意图:

if (!!(val & 0x01) + !!(val & 0x02) + !!(val & 0x04) + !!(val & 0x08) >= 3)

答案 7 :(得分:1)

int x = val & 0x0f;    // mask to keep only the interesting bits

switch (x) {
    case  7:  // 0b0111 ==  7
    case 11:  // 0b1011 == 11
    case 13:  // 0b1101 == 13
    case 14:  // 0b1110 == 14
    case 15:  // 0b1111 == 15
        // at least 3 bits are set
        // do whatever you need, like

        printf("asdjfkadscjas \n");
        break;
}

它并不是特别聪明,但我认为下一个出现并查看代码的针头将没有问题,弄清楚意图是什么以及它是否正确。这是一个非常大的优点,当我试图弄清楚我上周在该功能中做了什么时,那个针头。

答案 8 :(得分:0)

伪代码:

int set = 0;
for(i = 0 to 3)
    set++ if val & (1<<i)
if(set >= 3)
    ...

答案 9 :(得分:0)

count  =  (val >> 1) & 1 + (val >> 2)&1 + (val >> 3)&1 + (val&1)

count  =  precalculated_counts[val & 0x0F];

答案 10 :(得分:0)

unsigned nNumOfBitEnabled=0;
    for(unsigned nBit=0; nBit<4; ++nBit)
    {
        // Check bit state
        if ((val >> nBit) & 0x1)
        {
            ++nNumOfBitEnabled;
        }
    }

答案 11 :(得分:0)

有趣的是这个问题 - 我想我知道一个聪明的答案“这个值设置了多少位”

#include <stdint.h>
#include <stdio.h>

uint8_t NumBitsSet(uint32_t value){
   uint8_t num_bits_set = 0;
   while(value != 0){
     value = value & (value-1);
     num_bits_set++;
   }

   return num_bits_set;
}

int main(int argc, char *argv[]){
  uint32_t value = 2147483648;
  printf("numbits set in %x = %d", value, NumBitsSet(value));
  return 0;
}

您可以使用此作为确定完全一位是否设置的基础,但您必须对零进行特殊检查。

uint8_t exactly_one_bit_set = (value & (value-1)) == 0 ? 1 : 0;

这里的技巧是,如果一个值设置了一个比特,那么一个比该值小的值将使该比特设置之下的所有比特都被清除。把这两件事放在一起总是零。