如何获得第n位值

时间:2014-12-10 22:25:34

标签: c++ bit-shift bits

我对整个比特转换和c ++都很新。

让我说我有uint8_t 00100100(36),我想检查第3位是否已设置。 以下是我现在只做一点的代码。

uint8_t x = 36;
    if(x&1<<3)
        printf("is set");

如何检查第6位 OR 是否已设置?我想检查几个比特组合,如第5或第7或第8。

最优雅的方式是什么?

3 个答案:

答案 0 :(得分:11)

通过数字位置检查位是正确的方法之一,但它使得代码依赖于幻数,这使得它更难以阅读和维护。

通常,在检查位掩码时,有一个目标是检查一些特定的标志,让我们说一个硬件寄存器。

想象一下,例如你的整数中的每一位代表你家中的特定灯光,你想检查浴室和厨房是否亮着:

enum LightMask {
    ENTRANCE = 0x01,
    LIVING_ROOM = 0x02,
    RESTROOM = 0x04,
    KITCHEN = 0x08,
    BATHROOM = 0x10,
    BEDROOM1 = 0x20,
    BEDROOM2 = 0x40,
    ATTIC = 0x80
};

uint8_t lightsOn = GetLightsOn();

if (lightsOn & (BATHROOM | KITCHEN)) {
     // ...
}

这是优雅,易于理解,可以很容易地修改。

如果你想明确地使用位位置而不是常量,那么枚举也可以用编译器的免费位表示来表达:

enum LightMask {
    ENTRANCE    = 1 << 0,
    LIVING_ROOM = 1 << 1,
    RESTROOM    = 1 << 2,
    KITCHEN     = 1 << 3,
    BATHROOM    = 1 << 4,
    BEDROOM1    = 1 << 5,
    BEDROOM2    = 1 << 6,
    ATTIC       = 1 << 7
};

答案 1 :(得分:3)

如果您不知道要在运行时检查哪个位位置,一种方法是创建一个函数,以便您可以为要检查的任何第n位调用它:

bool IsBitSet(uint8_t num, int bit)
{
    return 1 == ( (num >> bit) & 1);
}

uint8_t x = 37; //00100101
for (int i = 0; i < 8; ++i)
{
    if ( IsBitSet(x, i) )
        printf("%dth bit is set\n", i);
    else
        printf("%dth bit not set\n", i);
}

输出结果为:

0th bit is set
1th bit is not set
2th bit is set
3th bit is not set
4th bit is not set
5th bit is set
6th bit is not set
7th bit is not set

如果我想检查是否设置了第3位或第6位:

uint8_t x = 36; //00100100
if ( IsBitSet(x, 2) || IsBitSet(x, 5) )
    printf("bit 3 and/or bit 6 is set\n");

你也可以使这个功能inline 可能提高效率。

答案 2 :(得分:1)

uint8_t x = 36;
if (x & ((1 << 2) | (1 << 5)))
    printf("is set");

或者你知道hex:

uint8_t x = 36;
if (x & 0x24)
    printf("is set");