我试图在一个字符中表示一组值:前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
}
那么,用最后两位来编码我想做的事情的最佳方法是什么?
我还没有做过任何性能测试,因为我还没有弄清楚如何编写代码,但我认为这是进行此类操作的最快方法。
[顺便说一句,这可能闻起来像是家庭作业,但我只是一只54岁的狗,正在尝试学习一些新的技巧。]
最佳答案
这在某种程度上取决于您是否需要单独处理这两个位,作为介于0和3之间的(十进制)值,或者您是否总是将它们视为一个字节的上两个位。
这里有一种方法,我们只是屏蔽掉所有其他位,并将条件定义为这两个位在一个字节中的上两个位的值。
#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,这是十六进制的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)