This is a really smart trick that changes a bit without branching. Here's an explanation assuming that you understand how bitwise operators work.
Let's start by rearranging the expression
(-val ^ command) & (1 << bit_nr)
First, let swap -val and command
(command ^ -val) & (1 << bit_nr)
Then we apply the distribution law
(command & (1 << bit_nr)) ^ (-val & (1 << bit_nr))
Now understand that (under the condition of two additions), if val is 0, -val is 0 (no bits), and if val is 1, -val is -1 (all bits are set)
(command & (1 << bit_nr)) ^ (val ? (1 << bit_nr) : 0)
Thus, the assignment can be rewritten as if-statement
if (val) command ^= (command & (1 << bit_nr)) ^ (1 << bit_nr); else command ^= command & (1 << bit_nr);
If val is 1, the bit at bit_nr has XORed with its negative value, which always sets the bit. If val is 0, the bit is XORed with itself, which always clears the bit. All other XORed bits are 0, which leaves them unchanged.
Here's a more readable, unbranched version that handles the bitwise action for the shift:
uint16_t change_bit(uint16_t command, unsigned int bit_nr, unsigned int val) {
nwellnhof
source share