Can someone explain to me how XOR swapping of two variables with no temp variable works?
void xorSwap (int *x, int *y) { if (x != y) { *x ^= *y; *y ^= *x; *x ^= *y; } }
I understand WHAT it does, but can someone walk me through the logic of how it works?
The bitwise XOR operator can be used to swap two variables. The XOR of two numbers x and y returns a number that has all the bits as 1 wherever bits of x and y differ. For example, XOR of 10 (In Binary 1010) and 5 (In Binary 0101) is 1111, and XOR of 7 (0111) and 5 (0101) is (0010).
We can use the bitwise XOR operator to swap two numbers without using the swap() method and third variable. We must follow the steps given below: Find the binary equivalent of given variables, say X and Y. Find X^Y and store it in x, i.e. X = X ^ Y.
(eXclusive OR) A Boolean logic operation that is widely used in cryptography as well as in generating parity bits for error checking and fault tolerance. XOR compares two input bits and generates one output bit. The logic is simple. If the bits are the same, the result is 0. If the bits are different, the result is 1.
You can see how it works by doing the substitution:
x1 = x0 xor y0 y2 = x1 xor y0 x2 = x1 xor y2
Substituting,
x1 = x0 xor y0 y2 = (x0 xor y0) xor y0 x2 = (x0 xor y0) xor ((x0 xor y0) xor y0)
Because xor is fully associative and commutative:
y2 = x0 xor (y0 xor y0) x2 = (x0 xor x0) xor (y0 xor y0) xor y0
Since x xor x == 0
for any x,
y2 = x0 xor 0 x2 = 0 xor 0 xor y0
And since x xor 0 == x
for any x,
y2 = x0 x2 = y0
And the swap is done.
Other people have explained it, now I want to explain why it was a good idea, but now isn't.
Back in the day when we had simple single cycle or multi-cycle CPUs, it was cheaper to use this trick to avoid costly memory dereferences or spilling registers to the stack. However, we now have CPUs with massive pipelines instead. The P4's pipeline ranged from having 20 to 31 (or so) stages in their pipelines, where any dependence between reading and writing to a register could cause the whole thing to stall. The xor swap has some very heavy dependencies between A and B that don't actually matter at all but stall the pipeline in practice. A stalled pipeline causes a slow code path, and if this swap's in your inner loop, you're going to be moving very slowly.
In general practice, your compiler can figure out what you really want to do when you do a swap with a temp variable and can compile it to a single XCHG instruction. Using the xor swap makes it much harder for the compiler to guess your intent and therefore much less likely to optimize it correctly. Not to mention code maintenance, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With