halO

programming, hackery, rants, science and of course Opera

Switch two variables without using a temporary stand-in

, , ,

I remember "learning" this trick 6 years ago, but since I never understood how it worked I quickly forgot it again. Since I stumbled upon it again, I decided to have a look at why it worked so I'd remember it in case I ever get a use for it - like how I know that a second, since World War II, has been defined as the time it takes the cesium 133 atom to oscillate 9 192 631 770 times. (And now this is obsolete for some other atom with a number so much larger it's not even funny, but sad, to remember).

The trick is to use bitwise XOR on two variables in a specific pattern so they switch their values such that A contains what B had, and vice versa. This isn't actually terribly useful for most programmers to know since memory restrictions aren't exactly quite what they used to be, but as an amusing puzzle it's worth mentioning.

So spelled out in javascript, we could demonstrate the princible by the following code:

var a = 5;
var b = 3;
a = a^b;
b = a^b;
a = a^b;
alert('a is '+a+' and b is '+b);

To test it, copy the following into your address bar and hit <enter>: javascript:var a=5;var b=3;a=a^b;b=a^b;a=a^b;alert('a is '+a+' and b is '+b);

The output should tell you that a is 3 and b is 5, even though we initialized a as 5 and b as 3. The reason it works is that all four possible combinations of bit patterns are switched to their opposite by performing the same XOR operations, as we shall see:

Initial values 1st pass 2nd pass 3rd pass
a b a=a^b b=a^b a=a^b
0 0 0 0 0 0 0 0
0 1 1 1 1 0 1 0
1 1 0 1 0 1 1 1
1 0 1 0 1 1 0 1

In my eyes, the beauty in this is that there are no if-else statements or special conditions. Everything works by a simple bitwise operator, making it very fast and memory preserving to boot! ...albeit very little memory. Absolutely everything that can be expressed as a bitstream can theoretically be switched in this fashion, though language restrictions usually prevent you from doing this on strings.

The pleasure of finding things outFreeze page

Comments

Unregistered user Thursday, September 17, 2009 1:48:37 PM

Kieran writes: This can be done another way, a little more mathematical... (in c# :) int A = (random number 1) int B = (random number 2) A += B B -= (A-B) A -= (A-B)/2 B = A-B Basically using the A-B as a 3rd variable without writing a temporary variable, int C.

Unregistered user Friday, March 19, 2010 7:46:20 AM

vikram writes: another simple way is int a=randomnumber; int b=randomnumber; a=a+b; b=a-b; a=a-b;

Unregistered user Thursday, November 18, 2010 11:23:07 PM

Anonymous writes: a=a-b b=a+b a=b-a this is another way

Unregistered user Tuesday, February 15, 2011 8:16:02 PM

Anonymous writes: The Mathematical Way explained: A' = original A B' = original B A = A'+B' = Sum B = A'-B' = Diff B = (Sum + Diff) / 2 = A' A = Sum - A' = B'

Unregistered user Thursday, January 19, 2012 6:35:14 AM

Dine1504 writes: #include void change(int *,int*); int main () { int a=2,b=5; printf("Before : a=%d,b=%d\n",a,b); change(&a,&b); printf("After : a=%d,b=%d\n",a,b); return 0; } void change(int *a,int *b){ *a += *b; *b = *a-*b; *a = *a-*b; }

Write a comment

New comments have been disabled for this post.