The below routine is expected to swap the values of a
and b
a = a ^ b
b = b ^ a
a = a ^ b
Let's analyze to see how and why the swap works.
For that, let's not swap the values, but store them in separate variables, so we can see what exactly goes on.
a0 = a ^ b
b1 = b ^ a0
a1 = a0 ^ b1
Simplifying the equations using below properties of XOR. Check XOR Properties@Wikipedia for reference
- commutative (
a ^ b == b ^ a
)
- associative (
a ^ (b ^ c) == (a ^ b) ^ c
)
a ^ a == 0
0 ^ a == a
a0 = a ^ b // Equation #1
b1 = b ^ a0
a1 = a0 ^ b1
b1 = b ^ a0 // Equation #2
= b ^ (a ^ b) // Using Equation #1
= b ^ (b ^ a) // Property #1
= (b ^ b) ^ a // Property #2
= 0 ^ a // Property #3
= a // Property #4
a1 = a0 ^ b1
= a0 ^ (b ^ a0) // Using Equation #2
= (a ^ b) ^ (b ^ (a ^ b)) // Using Equation #1
= (b ^ a) ^ (b ^ (b ^ a)) // Using Property #1
= (b ^ a) ^ ((b ^ b) ^ a) // Using Property #2
= (b ^ a) ^ (0 ^ a) // Using Property #3
= (b ^ a) ^ a // Using Property #4
= b ^ (a ^ a) // Using Property #2
= b ^ 0 // Using Property #3
= b // Using Property #4
As you can see, b1
now contains the original value of a
and a1
contains the original value of b
, i.e. the values of b
and a
are swapped
In summary, a^=b;b^=a;a^=b
is just an idiomatic expression, nothing magical in it :)
Plain English explanation for the same
XOR sets the bits when the operand bits are dissimilar and resets the bits otherwise
Let's walk through the transformations that take place with an example. For that let's say, we have the following numbers (in binary) assigned to the variables.
a = 1 1 0 0
b = 1 0 1 0
Step #1: a = a ^ b
// CREATE A MASK
a = 0 1 1 0
b = 1 0 1 0
Imagine the new value of a
is a mask for generating the old value of a
given b
or generating the old value of b
given a
.
Step #2: b = b ^ a
// Recover original value of a
using mask and original value of b
a = 0 1 1 0
b = 1 1 0 0
Since b
is still preserved/untouched, we can recover original value of a
with the mask - which is what we did in this step
Step #3: a = a ^ b
// Recover original value of b
using mask and original value of a
a = 1 0 1 0
b = 1 1 0 0
Now we have the original value of a
in variable b
, so we can use our same mask to recover the original value of b
. We can overwrite the mask now, since we don't need the mask after this step.