[Math] Logic behind bitwise operators in C

bit-stringslogic

I came across bitwise operations in C programming, and I realized that XOR operator can be used to swap 2 numbers in their binary bases. For example let $$i=(65)_{10}=(1000001)_{2}, \text{ and } j=(120)_{10}=(1111000)_{2}$$.

Let $\oplus$ be the XOR operator, then observe that if I started with any one of them, say $i$ and following the following procedure:

1)replace its value with the $\oplus$ value, yielding $$i=(0111001)_{2},j=(1111000)_{2}$$

2) replace the other variable($j$) with another $\oplus$ value derived from the new $i$ and old $j$, yielding $$i=(0111001)_{2},j=(1000001)_{2}$$

3)replace the original variable $i$ with $\oplus$ value again, yielding $$i=(1111000)_{2},j=(1000001)_{2}$$

which shows that we would somehow have their values swapped. I found this way of programming online and I definitely can’t understand how people think of the logic aspect of this. I would think it’s linked to the truth table as follows, which shows by division of cases that the values can be swapped.

enter image description here

However, I am still uncertain about the full reasoning why this works, like whether there is any mathematical theorems that I should know that can aid me in my understanding.

PS: Sorry if the question is off-topic here, it feels like a programming question, but I feel that I more concerned about the “logic” rather than the programming. I also drew the table myself on MS word since I can't get the latex one to work somehow.

Best Answer

Note that you can do the same thing without bitwise operators (at least for unsigned integer types since they can't overflow into undefined behavior):

        // i == x     j == y
i += j; // i == x+y   j == y
j -= i; // i == x+y   j == -x
i += j; // i == y     j == -x
j = -j; // i == y     j == x

Now if we do this bit for bit, but modulo 2 instead of modulo UINT_MAX+1, the XOR operation implements both addition and subtraction, and the final negation is a no-op because $-1\equiv 1$ and $-0\equiv 0 \pmod 2$. So what is left in the bitwise version is exactly

i ^= j; j ^= i; i ^= j;
Related Question