打开和关闭位的最优雅的方式

时间:2019-06-26 02:33:55

标签: c

我有一个寄存器,可以是0x02或0x01(0010或0001)。在单个操作中设置位的最优雅方法是什么?例如。如果寄存器当前为0x02,则需要关闭位2并打开位1。

非常感谢

3 个答案:

答案 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 0x02x = (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”

请注意,只有当整个值为一或二时,这些才有意义。如果您想摆弄这些位并将其他位设置为当前值,则需要第一个选项。