1

我试图在一个字符中表示一堆值:前 6 位中有 6 个开/关标志,并使用最后 2 位来保存 4 个不同的值。这似乎很基本,以至于像这样的宏必须存在于某个地方,但我找不到它们。

 #define HOT 0x00
 #define BIG 0x01
 #define FAT 0x02
 #define HIT 0x03
 #define BAT 0x04
 #define ZAX 0x05    
 #define HOW 0x06

 #define TWO_BITS     nnn    // ???
 #define CONDITION_0  nnn   // bit combo: 00
 #define CONDITION_1  nnn   // bit combo: 01
 #define CONDITION_2  nnn   // bit combo: 10
 #define CONDITION_3  nnn   // bit combo: 11

void bitter(void)
{
    unsigned char myBits = 0;
    bool nonsense;

    if (myBits & BIG)  nonsense = true;    // BIG flag on   
    if (!(myBits & BAT)) nonsense = false; // BAT flag off

    myBits = myBits | BIG;     // turn on BIG bit
    myBits = myBits & ~BIG;    // turn off BIG bit

    if (TWO_BITS == CONDITION_0)
        doThis();
    else if (TWO_BITS == CONDITION_1_)
        doThat();
    // ... etc

}

那么,用最后 2 位编码我想做什么的最佳方法是什么?我无法进行任何性能测试,因为我还没有弄清楚如何编写代码,但我假设这是进行此类操作的最快方法。

[顺便说一句,这可能闻起来像家庭作业,但我只是一只 54 岁的狗,正在努力学习一些新技巧。]

4

3 回答 3

1

我不确定我理解你想要什么,但听起来你想检查是否设置了两个位。在这种情况下,例如,如果你想检查最后两位是否都设置了,你会这样做:

((myBits & 3) == 3)
于 2012-05-11T19:37:45.647 回答
1

您只需对最后 2 位 (0x03) 应用位掩码并打开结果:

switch (myBits & 0x03) {
    case 0: // CONDITION_0
        doThis();
        break;
    case 1: // CONDITION_1
        doThat();
        break;
    case 2: // CONDITION_2
    case 3: // CONDITION_3
}

此外,如果您希望它们作为宏来重用它们:

#define CONDITION_0(X) (((X) & 0x03) == 0)
#define CONDITION_1(X) (((X) & 0x03) == 1)
#define CONDITION_2(X) (((X) & 0x03) == 2)
#define CONDITION_3(X) (((X) & 0x03) == 3)

然后你只需要写一些类似的东西:

if (CONDITION_0(myBits)) {
    doThis();
} else if (CONDITION_1(myBits)) {
    doThat();
}
于 2012-05-11T19:42:34.103 回答
1

这有点取决于您是否需要自己处理这 2 位,作为 0 到 3 之间的(十进制)值,或者是否始终将它们视为字节的高 2 位。

这是一种方法,我们只是屏蔽掉所有其他位,并将条件定义为这 2 位将作为一个字节中的高 2 位的值。

 #define TWO_BITS(x) ((x) & 0xC0)

 #define CONDITION_0  0
 #define CONDITION_1  0x40   // bit combo: 01
 #define CONDITION_2  0x80   // bit combo: 10
 #define CONDITION_3  0xC0   // bit combo: 11

也就是说,一个字节的高 2 位是二进制的 1 1 0 0 0 0 0 0 ,即十六进制的 0xC0 。高 2 位为 0 1 ,即一个字节中的所有位为 0 1 0 0 0 0 0 0 ,即十六进制的 0x40 。

你的测试必须是

if (TWO_BITS(myBits) == CONDITION_0)

另一种方法是将那些高 2 位提取为 2 位整数(即 0 到 3 之间的值)。这很简单,只需将位向右移动 6 位。

 #define TWO_BITS(x) ((x) >> 6)

 #define CONDITION_0  0x0
 #define CONDITION_1  0x01   // bit combo: 01
 #define CONDITION_2  0x02   // bit combo: 10
 #define CONDITION_3  0x03   // bit combo: 11

测试条件之一时,用法相同。

 if (TWO_BITS(myBits) == CONDITION_0)

最后一点,您的低 6 位标志似乎有点错误,请考虑例如

#define HOW 0x06

0x06 是二进制值 0 0 0 0 0 1 1 0 ,因此实际上是打开或测试 2 位。您可能希望将 1 位与 1 个标志相关联,这将是这个序列

 #define BIG 0x01
 #define FAT 0x02
 #define HIT 0x04
 #define BAT 0x08
 #define ZAX 0x10
 #define HOW 0x20

这通常写为位移位,因此很容易读取它是哪个位:

 #define BIG (1 << 0)  //bit zero
 #define FAT (1 << 1)  //bit 1
 #define HIT (1 << 2)  //bit 2
 #define BAT (1 << 3)  //bit 3 , etc.
 #define ZAX (1 << 4)
 #define HOW (1 << 5)
于 2012-05-11T19:49:36.370 回答