Swap two variables using XOR

Most people would swap two variables x and y using a temporary variable, like this:

Here’s a neat programming trick to swap two values without needing a temp:


This is a companion discussion topic for the original entry at http://betterexplained.com/articles/swap-two-variables-using-xor/

Note that in portable C (that is, according to, say, the 1999 C standard), this only works for unsigned integral types. Obviously it won’t work for floating point or pointer or struct/union types. (Portably – if you don’t care about machine-specific code, you could convert pointers to integers on many platforms and it’ll just do what you want. But it’s not guaranteed to work everywhere.)

But also, under some (rare, but allowed) non-2s-complement signed integer representations, an xor might result in a “negative zero” that can be converted to a normal zero before continuing, resulting in the wrong sign bit setting on an output value…

Wow, thanks for the details Ken! Yeah, I imagine there are all sorts of nasty side effects when using a trick like this. Appreciate the background info.

Hi! I think the following note will be helpful, since it highlights the properties involved in all these swappings:

http://www.cs.nott.ac.uk/~jff/papers/JFFs/JFF1.pdf

Thanks Joao, that paper is pretty interesting.

Kalid,

I’ve just published a new version of my note on this. You can find it at:

http://www.joaoferreira.org/2007/07/11/swapping-the-values-of-two-variables/

[…] void swap (int& a, int& b) { a ^= b; // a = a XOR b b ^= a; // b = b XOR a a ^= b; // a = a XOR b } Why does it work? Here is one that explains it well: Swap two variables using XOR | BetterExplained I found another article on the same technique, along with two other techniques. However, I caution you to read the comments that follow it: 3 ways to swap variables without temp variable « Stream As the betterexplained.com article mentions, there is an XCHG instruction on some machines that allows you to swap two registers without using multiple XOR instructions. The important thing: be careful when using such unusual techniques. You never know how a program can be affected by a compiler, an assembler or libraries that are linked it. Only use it if absolutely necessary or if you merely wish to play with it in a small program. Back on-topic, those were examples of using bitwise operations to increase efficiency. Multiplication and division by 2 is fairly simple too when you only need to worry about integers. All that is required is knowledge of what operators that bit shifts use in your specific programming language, if the operation is supported in your programming language (Visual Basic does not support bit shifts natively). In C/C++ and Java, the operator is "<<" for a left shift (SHL/SAL in ASM) and ">>" for a right shift (SHR/SAR in ASM - which one is used can depend upon signedness of a value except in Java where all integers are signed integers). The bottom line: ASM is useful and the ASM ways that were used for efficiency are still quite useful at times. __________________ […]

there is another way, tho i doubt if it’s faster,

a=10;
b=15;

a=a+b;//a=25 b=15
b=a-b; //a=25 b=10
a=a-b; //a=15 b=10, swapped

Hi zezima, thanks for the info! That’s a neat trick too – you “combine” a and b in a similar way, and extract them as well.

One thing to watch out for is arithmetic overflow.

[…] E aí pronto, suas variáveis estão invertidas. Pode acreditar (ou ler uma explicação bem mais detalhada). Legal né? […]

I followed you right through to the pointer Caveat. If both point to the same address it should still work…

x=1234
y=1234

x=x xor y -> x = 1234 xor 1234 -> x = 0
y=x xor y -> y = 0 xor 1234 -> y = 1234
x=x xor y -> x = 0 xor 1234 -> x = 1234

Hi Rich, good question.

When using pointers to the same location, when you do the first step (x = x xor y) => 0 you also set y to 0 as well since it’s at the same location. In this case, you’ve lost the value 1234 – x and y were sharing the same location and it was overwritten with 0.

Hope this helps.

in c this can be written as x^=y^=x^=y

@Anonymous: That’s right – in “slightly obfuscated” c :).

Pretty much any compiler ever will substitute the standard swap for a single exchange instruction. This means the extra variable never gets made (unless it is used later on), and the swap is only one instruction. The triple xor is not recognized as a swap (and can’t be, since the result is different when they are equal), so it is slower in the end, as well as harder to understand.

can i just make it like dis:
a=5
b=4
a=(a+b)-a
b=(b+a)-b
please help me…i really had a hard tym with this

can you please reconstruct my program…i am trying to retrieved the nth perfect number…this are my codes:
int no,you=6,div=1,they=0,her=0,as;
getch(); //the if statement will be executed if menu no. 3 is chosen
if(opt==3){
system(“color 33”);
cout>no;
while(her

Try this article at http://www.madanrevoor.com/c-programming/how-to-swap-two-variables-without-a-temp-variable

[…] http://betterexplained.com/articles/swap-two-variables-using-xor/ […]