-2

I've got a register which can either be 0x02 or 0x01 (0010 or 0001). What is the most elegant way of setting the bits in a single operation? E.g. if the register is currently 0x02, I need to turn off bit 2 and turn on bit 1.

Many thanks

John Smith
  • 465
  • 1
  • 4
  • 18

2 Answers2

1

x ^= 3 changes 1 to 2 and changes 2 to 1. ^ performs an exclusive or (XOR) operation.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

The most elegant way is to define a structure that uses bit fields. Sadly this is rarely appropriate when dealing with hardware registers (e.g. order of bits in a bit-field isn't well defined, etc).

Without bitfields; use "and with compliment" (e.g. x = x & ~ 2; or x &= ~2;) to clear bits and "or" (e.g. x = x | 1; or x |= 1;) to set bits.

If you know the previous value you can optimize further. For example, if you know the previous value is 0x02 then you can just set a new value (e.g. x = 0x01; // It was 0x02 or maybe x = (0x02 & ~2) | 1; so compiler will work out the constant for you but the source code still reflects how the constant was determined).

Note that it's not possible to do it in a single operation unless you do know something about the previous value. For example, if you know that the previous value will have bit 0 clear and bit 1 set but don't know anything about the other bits (and need to preserve the other bits), then you can decrement (x--; // Clear bit 2, set bit 1) or use exclusive OR.

Brendan
  • 35,656
  • 2
  • 39
  • 66