我正在尝试在一个char中表示一堆值:前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岁的狗试图学习一些新的技巧。]
答案 0 :(得分:1)
我不确定我理解你想要什么,但听起来你想检查是否设置了两个位。在这种情况下,例如,如果你想检查最后两位是否都设置了,你可以这样做:
((myBits & 3) == 3)
答案 1 :(得分: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();
}
答案 2 :(得分: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)