How to set and clear different bits with a single line of code (C)

夙愿已清 提交于 2019-12-20 03:12:17

问题


data |= (1 << 3) sets bit (3) without disrupting other bits. data &= ~(1 << 4) resets bit (4) without disrupting other bits. How can I accomplish both tasks in a single instruction?

(As this is really only for readability, I plan on #defineing this in a cute way like #define gpioHigh(x) <insert code>. The alternative is to figure out how to correctly pass a gpio pointer into functions that I write expressly for this purpose, but eff that)

Thanks!

Mike


回答1:


It's not possible in a single instruction. This is because there are 3 possible operations you need to do on the different bits:

  • Set them (bit 3)
  • Clear them (bit 4)
  • Leave them alone (all the other bits)

How can you select from one of three possibilities with a bitmask made up of binary digits?

Of course, you can do it with one line e.g:

data = (data | (1 << 3)) & ~(1 << 4)



回答2:


You can't.

That is, if you want to explicitly ensure bx set and by clear - if you just want to flip them (regardless of prior value), you can XOR with operator^ as others have pointed out.

To see why this can't be done in one instruction (of course, you can easily combine two or more instructions into a single LOC), consider the following truth table:

B|A|Q
-----
0|0|x
0|1|0
1|0|1
1|1|x

where the "don't care" xs are irrelevant to discussion. No logical operator has this function - how could it? How can we determine which is B and which is A if the two inputs are of differing value*? That's at the heart of your problem.

However, consider that cramming this into one instruction perhaps doesn't achieve your stated readability aim anyway. In fact if anything, the two separately is more readable - and can still be invoked by some set3clear4().


NB - and this is way off on a tangent - that truth table can be implemented by so-called 'Logic Elements' in FPGA architectures, as they're constructed from 'look-up tables' (LUTs) essentially ROM where the inputs A,B,... index into the table to find the value Q. And of course, A¬B corresponds to an address different to ¬AB.



来源:https://stackoverflow.com/questions/30406420/how-to-set-and-clear-different-bits-with-a-single-line-of-code-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!