C ++位域测试

时间:2010-12-23 00:30:12

标签: c++ bits

是否有比这更简洁的比较方式(我知道的唯一方法):

#define BIT1 1
#define BIT2 2
#define BIT3 4
#define BIT4 8
#define BIT5 16
#define BIT6 32

// I declare this somewhere in a structure
unsigned char bits: 6;

// I want all of them to be 0 at first (000000)
bits = 0;

/* I do some bite setting here */

// I only want to know if the state of my bits == 000000
if(bits & (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) == (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6))
{
    // All kinds of nasty stuff
}

我认为可能是bits & 0x00 == 0x00

的内容

4 个答案:

答案 0 :(得分:2)

如果您想要 compact (如评论所示)而不是快速,为什么不这样做:

#define BIT1 0x01
#define BIT2 0x02
#define BIT3 0x04
#define BIT4 0x08
#define BIT5 0x10
#define BIT6 0x20
#define BITS1THRU4 (BIT1|BIT2|BIT3|BIT4)
// or #define BITS1THRU6 0x0f

// I declare this somewhere in a structure
unsigned char bits: 6;

// I want all of them to be 0 at first (000000)
bits = 0;

/* I do some bit setting here */

// I only want to know if the state of my first four bits == 0000
if(bits & BITS1THRU4 == 0) ...

它可能不会更快,因为你的原始代码无论如何都会变成那个常量,但它可能更具可读性(这通常是一个很好的理由)。

如果您需要其他变体,请定义它们。如果它们太多(63个定义,如果你全部使用它们,可能会有点偏高),我会开始考虑另一个解决方案。

但是,说实话,除非你要为定义使用更有意义的名字,否则我只是抛弃它们。名称BIT3确实不会向0x04添加任何理解位模式的内容。如果它像UART_READ_READY_BIT那样,那就没问题,但你所拥有的只是略好于:

#define THREE 3

(没有违法行为,我只是指出我的观点)。我只是计算出位模式并将它们直接放在代码中(在你的情况下,第1位到第6位是0x3f)。

另外,对于你的特殊情况,我认为bits只会是那六位,所以你可能会发现它足以将它与0进行比较(没有位掩码)。如果你想要一个用于检查特定位的模式通用解决方案,我已经离开了位掩码方法。

答案 1 :(得分:0)

if( ~bits & (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) == (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6))

关于速度(BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)实际编译为常量,只有少数操作(如2),如果 - 一个NOR和一个比较(我不确定是否x386)支持NOR,但我认为确实如此)

答案 2 :(得分:0)

虽然这只是一个注释, 运算符==的优先级高于&, 逻辑 - 并且应该括在括号中:

if((a & b) == c)

我解释说这是提问者的意图。

(我认为这应该仅作为评论发布, 但似乎我不能发表评论)

答案 3 :(得分:0)

如果我正确读取您的条件(使用更正的括号,根据@ user547710),您可以检查所有位是设置,而不是零。

无论如何,您可以通过(1u << 6) - 1更紧凑地定义位1-6的掩码。这是编译时常量表达式,因此您无需担心额外的计算时间。我会这样做:

const unsigned char bitmask6 = 1u << 6) - 1;

if ((bits & bitmask6) == bitmask6)