Archived

This topic is now archived and is closed to further replies.

Swapping two integers without a temp variable

This topic is 5887 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

bishop_pass, it would be even better to write the macro as:

#define swapi(x,y) \
do { \
int temp; \
temp = x; \
x = y; \
y = temp; \
} while (0)


since your version will cause a syntactic error if you write something like:


if (some_condition)
swap(x,y);
else
whatever();

The semi-colon after swap wouldn''t be allowed unless you have the do-while wrapper.
(I know, I''m being picky )

Share this post


Link to post
Share on other sites
or just

#define swapi(x,y) \
{ \
int temp; \
temp = x; \
x = y; \
y = temp; \
}

seems dumb to put useless do while cases or if statements is you just want to preserve scope.

and, of course, an inline function is preferable to all of the above.

--michael

Share this post


Link to post
Share on other sites
quote:
Original post by chiuyan
seems dumb to put useless do while cases or if statements is you just want to preserve scope.


That''s not what he was talking about. He was talking about it having a syntax error due to the else after the macro''s use being left without an if.

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
Or using asm:

#define swap(a,b) \
\__asm
\{
\ mov eax, a
\ mov ebx, b
\ mov a, ebx
\ mov b, eax
\}

Which is probably what the compiler would do with your inline function anyway

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Maybe this is an option?

/* a = A and b = B */
a = a + b;
/* a = A + B and b = B */
b = a - b;
/* a = A + B and b = A */
a = a - b
/* a = B and b = A */

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
remember, though, that even asm uses hidden registers for swapping

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
WTH does do .. while(0) do for you!?

#define swapi(x,y) \
{ \
int temp; \
temp = x; \
x = y; \
y = temp; \
}

?


It stops problems in situations like this:

  
if( blah )
swapi( x, y );
else
swapi( a, b );


Your code would be expanded like this (formatted nicely):

  
if( blah )
{
int temp;
temp = x;
x = y;
y = temp;
};
else
{
int temp;
temp = a;
a = b;
b = temp;
};


Notice the '';'' before else. You can fix it by leaving the semi-colon off the end of the swap macro, but that doesn''t look as nice, and it''s easy enough to forget to leave it off.

The do...while(0) means you have to have the semi-colon on the end. It''ll work as expected in the above situation. It''ll also be optimized away by the compiler, so you won''t lose any speed.



codeka.com - Just click it.

Share this post


Link to post
Share on other sites
quote:
Original post by Martee
a = a ^ b;
b = a ^ b;
a = a ^ b;



Yup ... of course, the truly evil coder would write it as:

a ^= b ^= a ^= b;

I''m not really sure why you would want to avoid using a tempory variable. It''s not very clear what you are doing, and very rarely takes fewer instructions. It doesn''t even save you that much typing, especially if you use the longhand version.

temp = a;
a = b;
b = temp;

Is much clearer. I tried this trick on a 68k processor several years back, and discovered the variables I most often swapped were addresses, and as such had to be copied out of address registers into data registers to apply the XOR to them, thus saving absolutely no time or space whatsoever.

As a lesson in obfuscation, it can''t be beat though



--

MP3 Dancer

Get A Stripper on your desktop

Share this post


Link to post
Share on other sites
quote:
Original post by Martee
a = a ^ b;
b = a ^ b;
a = a ^ b;



Dangerous. You have to be sure you are not swapping the same variables.

ie.

int i = 4;
swap(i,i); // Bang

The safest method is still with to go with the temporary. Why do you think the std::swap is not implemented otherwise?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
USING A TEMP VARIABLE IS SLOWER THAN THE XOR THING...the xor intruction is only one cycle when done with the registers...the temp variable thing causes at least three instruction performed in memory which is avtually about 3cycles

and lastly, why would you perform this on the same variable...thats just slow coding if you have a program designed where that COULD happen

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
USING A TEMP VARIABLE IS SLOWER THAN THE XOR THING...the xor intruction is only one cycle when done with the registers...the temp variable thing causes at least three instruction performed in memory which is avtually about 3cycles


If you''re doing it with registers why wouldn''t you use xchg? The XOR trick was because some older CPU''s didn''t have xchg, and they needed a quick way to swap registers. How can you be sure you''re data is always in registers anyway? Your compiler will figure it out and implement the swap in the quickest way possible according to the situation, so you just use the temporary variable.

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Oluseyi
--- quote ---
Dangerous. You have to be sure you are not swapping the same variables.
--- /quote ---

Fascinating:

int a = 4, b = 4;
a = a ^ b; // a = 0
b = a ^ b; // b = 4;
a = a ^ b; // a = 4

Appears to still work...



I wanna work for Microsoft!

Void said ''the same variable'', you''re using two different variables.


int a = 4;
swap(a,a);

would become:

int a = 4;
a = a ^ a; // a = 0
a = a ^ a; // a = 0
a = a ^ a; // a = 0

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I think these methods will work, and they''re both pretty fast.


a = a - b;
b = a + b; // b = (a-b) + b = a
a = b - a; // a = a - (a - b) = b


or you can use xor:
(this is just in pseudo-code)

a = a xor b;
b = a xor b; //b = (a xor b) xor b = a
a = a xor b; //a = (a xor b) xor a = b

Share this post


Link to post
Share on other sites
AH! I have been reading this post thinking that ^ was the power sign. I was like, what''s wrong with all of these guys...that doesn''t work. Then I realized it was the XOR operator.

Share this post


Link to post
Share on other sites