我有一个寄存器,可以是0x02或0x01(0010或0001)。在单个操作中设置位的最优雅方法是什么?例如。如果寄存器当前为0x02,则需要关闭位2并打开位1。
非常感谢
答案 0 :(得分:1)
x ^= 3
将1更改为2,并将2更改为1。^
执行异或或(XOR)操作。
答案 1 :(得分:0)
最优雅的方法是定义一个使用位字段的结构。遗憾的是,在处理硬件寄存器时,这几乎是不合适的(例如,位字段中的位顺序定义不明确,等等)。
没有位域;使用“和并称赞”(例如x = x & ~ 2;
或x &= ~2;
)清除位,使用“或”(例如x = x | 1;
或x |= 1;
)清除位。
如果您知道先前的值,则可以进一步优化。例如,如果您知道先前的值为0x02,则可以设置一个新值(例如x = 0x01; // It was 0x02
或x = (0x02 & ~2) | 1;
,这样编译器将为您计算出常量,但是源代码仍然反映了确定常数)。
请注意,除非您对先前的值有所了解,否则无法在单个操作中完成。例如,如果您知道先前的值将清除位0并设置位1,但对其他位一无所知(并且需要保留其他位),则可以递减(x--; // Clear bit 2, set bit 1
或使用异或。
答案 2 :(得分:-1)
有多种方法可以在值1和2之间进行交替,其中包括:
x = x ^ 3
x = 3 - x
x = (x % 2) + 1
x = (x == 1) ? 2 : 1
在所有这些中,我认为最后一个可读性,因为它清楚地标识了选择某些值的条件:“如果x为1,则选择2,否则选择1”
请注意,只有当整个值为一或二时,这些才有意义。如果您想摆弄这些位并将其他位设置为当前值,则需要第一个选项。