Exchange two variables without using a temporary variable

I would like to be able to exchange two variables without using a temporary variable in C #. It can be done?

decimal startAngle = Convert.ToDecimal(159.9); decimal stopAngle = Convert.ToDecimal(355.87); // Swap each: // startAngle becomes: 355.87 // stopAngle becomes: 159.9 
+46
c # algorithm swap
Apr 29 '09 at 23:09
source share
27 answers

First of all, replacing without a temporary variable in C # a is a very bad idea .

But for the sake of the answer, you can use this code:

 startAngle = startAngle + stopAngle; stopAngle = startAngle - stopAngle; startAngle = startAngle - stopAngle; 

However, problems can occur when rounding off if the two numbers are very different. This is due to the nature of floating point numbers.

If you want to hide the temporary variable, you can use the utility method:

 public static class Foo { public static void Swap<T> (ref T lhs, ref T rhs) { T temp = lhs; lhs = rhs; rhs = temp; } } 
+80
Apr 29 '09 at 23:20
source share

The correct way to replace two variables:

 decimal tempDecimal = startAngle; startAngle = stopAngle; stopAngle = tempDecimal; 

In other words, use a temporary variable.

There you have it. No ingenious tricks, no companions of your code, cursing you for decades, no entries in The Daily WTF , and don’t spend too much time trying to figure out why you needed it in one operation, since at the lowest level even the most difficult a language function is a series of simple operations.

A simple, understandable, easily understandable solution t = a; a = b; b = t; t = a; a = b; b = t; .

In my opinion, developers who try to use tricks, for example, "change variables without using a temporary" or "Duff device", just try to show how smart they are (and fail).

I liken them to those who read books with large books solely in order to seem more interesting at parties (as opposed to expanding your horizons).

The solutions you add and subtract to, or based on XOR, are less readable and most likely slower than the simple "temp variable" solution (arithmetic / boolean-ops instead of simple assembly-level moves).

Do it yourself and other services by writing good, readable code.

This is my rant. Thank you for listening: -)

Aside, I fully understand that this does not answer your specific question (and I will apologize for it), but there are many precedents on SO where people asked how to do something and the correct answer is β€œDo not do this.”

+195
Apr 30 '09 at 2:05
source share

Yes, use this code:

 stopAngle = Convert.ToDecimal(159.9); startAngle = Convert.ToDecimal(355.87); 

The task is more difficult for any values. :-)

+66
Apr 29 '09 at 23:31
source share
 int a = 4, b = 6; a ^= b ^= a ^= b; 

Works for all types, including strings and floats.

+38
Dec 29 '09 at 7:34
source share

BenAlabaster showed a practical way to execute a variable switcher, but a try-catch clause is not required. This code is enough.

 static void Swap<T>(ref T x, ref T y) { T t = y; y = x; x = t; } 

Usage is the same as shown in the picture:

 float startAngle = 159.9F float stopAngle = 355.87F Swap(ref startAngle, ref stopAngle); 

You can also use the extension method:

 static class SwapExtension { public static T Swap<T>(this T x, ref T y) { T t = y; y = x; return t; } } 

Use it as follows:

 float startAngle = 159.9F; float stopAngle = 355.87F; startAngle = startAngle.Swap(ref stopAngle); 

Both methods use a temporary variable in the method, but you do not need a temporary variable in which you are exchanging.

+15
Mar 05 '13 at 18:17
source share

XOR binary exchange with a detailed example:

XOR truth table:

 aba^b 0 0 0 0 1 1 1 0 1 1 1 0 

Input:

 a = 4; b = 6; 

Step 1 : a = a ^ b

 a : 0100 b : 0110 a^b: 0010 = 2 = a 

Step 2 : b = a ^ b

 a : 0010 b : 0110 a^b: 0100 = 4 = b 

Step 3 : a = a ^ b

 a : 0010 b : 0100 a^b: 0110 = 6 = a 

Output:

 a = 6; b = 4; 
+14
Oct 27 '13 at 13:53 on
source share

C # 7 introduces the correct Tuples , which allows you to exchange two variables without a temporary:

 int a = 10; int b = 2; (a, b) = (b, a); 

This assigns b to a and a to b .

+14
Aug 28 '16 at 11:29
source share

Not in C #. You can use the triple-XOR trick in your own code, but not in a high-level language. (In any case, I heard that the XOR trick actually ends more slowly than using a temporary variable in many common processor architectures.)

You should just use a temporary variable. There is no reason why you cannot use them; this is not like a limited offer.

+11
Apr 29 '09 at 23:13
source share

For future students and humanity, I will send this correction to the currently selected answer.

If you want to avoid using temporary variables, there are only two reasonable parameters that take into account first performance and then readability.

  • Use a temporary variable in the general Swap method. (Absolute maximum performance, next to the temp built-in variable)
  • Use Interlocked.Exchange . (5.9 times slower on my machine, but this is your only option if multiple threads exchange these variables at the same time.)

Things you should never do:

  • Never use floating point arithmetic. (slow, round, and crowded errors, hard to understand).
  • Never use non-primitive arithmetic. (slow, overflow errors, hard to understand) Decimal not a processor primitive and provides much more code than you understand.
  • Never use an arithmetic period. Or a bit of hacks. (slow, hard to understand) This is a compiler. It can be optimized for different platforms.

Because everyone loves hard numbers, here is a program that compares your options. Run it in release mode from outside Visual Studio so that Swap is embedded. Results on my machine (Windows 7 64-bit i5-3470):

 Inline: 00:00:00.7351931 Call: 00:00:00.7483503 Interlocked: 00:00:04.4076651 

the code:

 class Program { static void Swap<T>(ref T obj1, ref T obj2) { var temp = obj1; obj1 = obj2; obj2 = temp; } static void Main(string[] args) { var a = new object(); var b = new object(); var s = new Stopwatch(); Swap(ref a, ref b); // JIT the swap method outside the stopwatch s.Restart(); for (var i = 0; i < 500000000; i++) { var temp = a; a = b; b = temp; } s.Stop(); Console.WriteLine("Inline temp: " + s.Elapsed); s.Restart(); for (var i = 0; i < 500000000; i++) { Swap(ref a, ref b); } s.Stop(); Console.WriteLine("Call: " + s.Elapsed); s.Restart(); for (var i = 0; i < 500000000; i++) { b = Interlocked.Exchange(ref a, b); } s.Stop(); Console.WriteLine("Interlocked: " + s.Elapsed); Console.ReadKey(); } } 
+10
Jul 18 '14 at 16:28
source share

<& outdated GT;

You can do this in 3 lines using basic math - in my example, I used multiplication, but a simple addition would also work.

 float startAngle = 159.9F; float stopAngle = 355.87F; startAngle = startAngle * stopAngle; stopAngle = startAngle / stopAngle; startAngle = startAngle / stopAngle; 

Edit: as noted in the comments, this will not work if y = 0, since it will create a division by zero error, which I did not consider. So an alternative representation of +/- would be a better way.

</ & outdated GT;




In order for my code to be immediately clear, I would rather do something similar. [Always think of the poor guy who should support your code]:

 static bool Swap<T>(ref T x, ref T y) { try { T t = y; y = x; x = t; return true; } catch { return false; } } 

And then you can do it in one line of code:

 float startAngle = 159.9F float stopAngle = 355.87F Swap<float>(ref startAngle, ref stopAngle); 

Or...

 MyObject obj1 = new MyObject("object1"); MyObject obj2 = new MyObject("object2"); Swap<MyObject>(ref obj1, ref obj2); 

Done, like dinner ... now you can go through any type of object and switch between them ...

+7
Apr 29 '09 at 23:32
source share

If you can refuse to use decimal to double , you can use the Interlocked class. This is supposedly a good way to share performance variables. Also read a bit than XOR.

 var startAngle = 159.9d; var stopAngle = 355.87d; stopAngle = Interlocked.Exchange(ref startAngle, stopAngle); 

Msdn: Interlocked.Exchange Method (Double, Double)

+6
Jul 30 '13 at 7:39 on
source share

For completeness, here is the XOR binary code:

 int x = 42; int y = 51236; x ^= y; y ^= x; x ^= y; 

This works for all atomic objects / references, since it concerns bytes directly, but may require an insecure context to work on decimals or, if you feel really distorted, pointers. And in some cases, it can be slower than a temporary variable.

+5
May 01 '09 at 9:42 a.m.
source share

Beware of your surroundings!

For example, this does not work in ECMAscript

 y ^= x ^= y ^= x; 

But it does

 x ^= y ^= x; y ^= x; 

My advice? Assume as little as possible.

+5
Oct 08 '10 at 3:21
source share
 a = a + b b = a - b a = a - b 

+3
Jul 05 '09 at 17:40
source share

A simple way to change 2 numbers on one line:

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

for example: a = 1, b = 2

Step 1: a = (1 + 2) - (b = 1)

Step 2: a = 3-1

=> a = 2 and b = 1




Effective way to use:

C Programming: (x ^= y), (y ^= x), (x ^= y);

Java: x = x ^ y ^ (y = x);

Python: x, y = y, x

Note: The most common error: // Swap using bitwise XOR (wrong solution in C / C ++)

 x ^= y ^= x ^= y; 

Source: GeeksforGeek

+3
May 05 '16 at 20:58
source share

For binary types, you can use this funky trick:

 a %= b %= a %= b; 

As long as a and b are not the same variable (e.g. aliases for the same memory), it works.

+2
Apr 29 '09 at 23:25
source share

Hope this helps ...

 using System; public class Program { public static void Main() { int a = 1234; int b = 4321; Console.WriteLine("Before: a {0} and b {1}", a, b); b = b - a; a = a + b; b = a - b; Console.WriteLine("After: a {0} and b {1}", a, b); } } 
+2
Mar 15 '16 at 23:49
source share
 startAngle = (startAngle + stopAngle) - (stopAngle = startAngle); 
+1
Feb 14 '15 at 9:30
source share

In C # 7:

 (startAngle, stopAngle) = (stopAngle, startAngle); 
+1
Sep 29 '17 at 13:39 on
source share

Here's a different approach on one line:

 decimal a = 159.9m; decimal b = 355.87m; a = b + (b = a) - b; 
0
Mar 24 '17 at 12:46 on
source share

we can do this with a simple trick

 a = 20; b = 30; a = a+b; // add both the number now a has value 50 b = ab; // here we are extracting one number from the sum by sub a = ab; // the number so obtained in above help us to fetch the alternate number from sum System.out.print("swapped numbers are a = "+ a+"b = "+ b); 
0
Jun 30 '17 at 17:37
source share

With C # 7, you can use tuple deconstruction to achieve the desired swap on a single line, and this is clear what happens.

 decimal startAngle = Convert.ToDecimal(159.9); decimal stopAngle = Convert.ToDecimal(355.87); (startAngle, stopAngle) = (stopAngle, startAngle); 
0
Jul 22 '17 at 1:12
source share

Here are some different ways to share two variables.

 //process one a=b+a; b=ab; a=ab; printf("a= %db= %d",a,b); //process two a=5; b=10; a=a+b-(b=a); printf("\na= %db= %d",a,b); //process three a=5; b=10; a=a^b; b=a^b; a=b^a; printf("\na= %db= %d",a,b); //process four a=5; b=10; a=b-~a-1; b=a+~b+1; a=a+~b+1; printf("\na= %db= %d",a,b); 
0
Aug 11 '17 at 19:16
source share

If you want to change two string variables:

 a = (a+b).Substring((b=a).Length); 
0
Aug 30 '17 at 14:07 on
source share
 var a = 15; var b = -214; a = b | !(b = a); 

This works great.

-one
Mar 30 '13 at 13:52
source share

Very simple code to replace two variables:

 static void Main(string[] args) { Console.WriteLine("Prof.Owais ahmed"); Console.WriteLine("Swapping two variables"); Console.WriteLine("Enter your first number "); int x = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Enter your first number "); int y = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("your vlaue of x is="+x+"\nyour value of y is="+y); int z = x; x = y; y = z; Console.WriteLine("after Swapping value of x is="+x+"/nyour value of y is="+y); Console.ReadLine(); } 
-2
Aug 09 '15 at 8:07
source share

You can try the following code. This is much better than other code.

 a = a + b; b = a - b; a = a - b; 
-2
Jun 23 '16 at 8:48
source share



All Articles