The Joy of
Programming
  C Traps and Pitfalls:
  Swapping Two Variables                                                   ...
Upcoming SlideShare
Loading in...5
×

05 Jo P May 07

191

Published on

Published in: Technology, Sports
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
191
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

05 Jo P May 07

  1. 1. The Joy of Programming C Traps and Pitfalls: Swapping Two Variables S.G. GANESH Let us look at the interesting problem of swapping two variables without using any temporary variables. We will discover the possible pitfalls of using smart ‘tricks’ to solve the problem. This column is to help students and novices understand C better. I t is assumed that the underlying machine follows 2’s void swap(float *i, float *j){ complement representation for integers and IEEE 754 *i = *i + *j; floating point standard for floating point numbers. *j = *i - *j; Let us look at a well-known trick of swapping two integers *i = *i - *j; without using any temporary variables, which uses arithmetic } operators + and -: float i = FLT_MAX; void swap(int *i, int *j){ float j = FLT_MAX; *i = *i + *j; printf(“Before swap : %f %fn”, i, j); *j = *i - *j; swap(&i, &j); *i = *i - *j; printf(“After swap : %f %f n”, i, j); } // prints // Before swap : 340282346638528860000000000000000000000.000000 Yes, we know it works. But does it really work in all cases? 340282346638528860000000000000000000000.000000 How about this code: // After swap : -1.#INF00 1.#INF00 GUEST COLUMN int arr[5] = {10,20,30,40,50}; Also, even for ordinary values, performing arithmetic int *ip = &arr[3]; operations can result in a loss of precision; so the swapped swap(ip,&arr[3]); values need not be exactly the same: for(int i = 0; i<5; i++) printf(“%d “, arr[i]); float i = 12345678.9f, p = i; // output: 10 20 30 0 50 float j = 98765432.1f, q = j; assert((i == p) && (j == q)); So, when the elements to be swapped happen to refer swap(&i, &j); to the same location, swapping fails. In the statement ‘*i= assert((i == q) && (j == p)); *i + *j;’, the implicit assumption is that *i and *j point to two different locations; this trick will not work if the // Assertion failed: (i == q) && (j == p), file E:tem.c, line 14 results of + and – operations are over-written. Here is a // abnormal program termination small test case just to demonstrate that: You can reasonably expect that the assertion will fail in this int x = 10; manner for many floating point numbers because arithmetic printf(“before calling swap, x = %d n”, x); operations with floats can result in some precision loss. But it swap (&x, &x); won’t fail for any of the integral values, as there is no possible printf(“after calling swap, x = %d”, x); precision loss for any integral arithmetic operations. // prints: before calling swap, x = 10 Another popular trick among students is to swap two // after calling swap, x = 0 variables using three repeated ex-or operations. Well, this solution also has many traps and pitfalls, and we’ll discuss There are other problems with this swap solution them in the next column. for integers, but for now, we’ll see if we can use this trick for swapping two floating point numbers. This solution doesn’t work for floats because the operation S.G. Ganesh is an engineer in Hewlett-Packard’s C++ ‘*i + *j’ might overflow. For integers, overflow can be compiler team. He has authored a book “Deep C” (ISBN 81- expected to result in rotation of values and it will work fine in 7656-501-6). He is also a member of the ANSI/ISO C++ Standardisation committee (JTC1/SC22/WG21), representing practice (try it!); it’s not the case with floating point overflow. HP. You can reach him at sgganesh@gmail.com. The following program shows this: www.linuxforu.com | LINUX FOR YOU | MAY 2007 73 CMYK

×