Sunday, December 05, 2004

C/C++: swap two numbers without using a temporary variable.

This is an old and infamous trick. I can't trace its origin. But if you do a little homework at 'Google University', you will find out this topic has been discussed many times online, especially at those programming forums. Rumor says this is a typical interview question. Well, I believe this one is no longer in use since it is already well-known to most programmers. However, it is still an interesting question and I think it is worth writing a note here as my first serious post.
Before we get started, I think it is reasonable to assume both numbers are of the same type. The first solution we might come up with is:

Solution (1)

a = a * b;
b = a / b;
a = a / b;

Obviously, there are two problems with this solution. Firstly, if number b equals zero, it will cause a division by zero, which gives undefined behavior. Secondly, the multiplication and division might cause overflow/underflow (the number is too small to represent). Note that underflow won’t occur when both numbers are integers. To fix the first problem, we can add a condition check. That is:

Solution (1a)

if (b!=0){
a = a * b;
b = a / b;
a = a / b;
}
else{
b = a;
a = 0;
}
Now, it is getting better, but the overflow/underflow problem still remains unsolved. Next, we might come up with another method based on additions and subtractions. That is our solution (2):

Solution (2)

a = a + b;
b = a - b;
a = a - b;

Solution (2) automatically avoids division by zero, but it still could cause overflow problems. Note that if both numbers are integers, the overflow problem is not as serious as it looks. Since addition and subtraction are modular in C, this solution works. It also holds for signed numbers as long as the negative numbers are represented via two complement. Similarly, we can do a subtraction first, and then an addition, and so on. And furthermore, we can add several condition checks and decide whether we should do a subtraction or an addition as the first step to avoid overflow. But that is not so fun any more.

The most interesting method is solution (3) that is based on 'exclusive or'.

Solution (3)

a = a ^ b;
b = a ^ b;
a = a ^ b;

XOR operation returns 1 when two bits are different; 0 otherwise. Note that this solution only works for integers.

0 Comments:

Post a Comment

<< Home