## DEV Community is a community of 607,823 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

loading... # How can you swap two variables without using a third? Nick Karnik Updated on ・1 min read

Moore's law is just an observation and not a real law like the Law of Gravity.

Over the years, developers have taken the increasing CPU speeds and Memory sizes for granted. Here's a warm-up interview question that I ask every candidate.

Let's assume the working memory for your function is 8-Bytes. You are given two 32-Bit Integers and you need to swap them. In other words, how can you swap two variables without using a third?

Please take your time to solve this and refrain from looking up solutions online or for answers below. This is your first step in becoming a Computer Scientist!

If you accepted this challenge, ❤️ it and follow me on Twitter.

## Discussion (131)  Nested Software • Edited

This is a rather beautiful "bit" of problem solving :)

It will work for both integers and floating points, positive and negative, and there is no issue with overflow. If someone can figure this out on their own, I think that's quite impressive. Most of us just know it from having seen it before though. DrBearhands • Edited

assuming cyclic overflows, i.e. INTMAX + 1 = INTMIN:
if `INTMAX - y < x` (equivalent to `x + y > INTMAX` without cycles)
then `x + y = INTMIN + y - (INTMAX - x - 1)`
ergo, rewriting the equations as
`x' = x + y`
`y' = x' - y`
`x'' = x' - y'`
we get:
`x' = INTMIN + y - (INTMAX - x - 1)`
`y' = x' - y`
`y' = INTMIN - (INTMAX - x - 1)`
`y' = INTMIN + 1 - INTMAX + x`
`y' = x`
`x'' = INTMIN + y - (INTMAX - x - 1) - y'`
`x'' = INTMIN + y - (INTMAX - x - 1) - x`
`x'' = INTMIN + y - INTMAX + x + 1 - x`
`x'' = INTMIN + 1 + y - INTMAX`
`x'' = y`

Overflows schmoverflows.

EDIT: Might be worth noting that this approach and the bitwise operator are essentially the same thing. Combine two things in a way that is reversible if you have either of the two originals.

Thread Theofanis Despoudis

Unfortunately that works in theory but in practice and most compilers do not guarantee that behavior. For example:

Java: Will back cycle to -2147483648
Javascript: will eventually print infinity if the value is too high
Go: Will not compile Lewis Cowles

limit x and y to 16 bit or store 32-bit numbers in 64-bit. max int for 64-bit signed or unsigned is twice that of it's 32-bit counterpart.

You cannot overcome size problem if it's expressed in bits. Only higher-order structures like arrays would enable that and then you are absolutely storing more than two variables (possibly more than one per entry if it's a pointer).

Thread simonhaisz • Edited

Good thing the question was specific to integers. With floating point arithmetic this wouldn't be guaranteed to work in all cases. Especially in Java 😭

This is probably the simplest case that shows the space vs time choice for optimisation. Here you are saving memory but have more operations. 3 arithmetic and 3 assignments. If you used an extra variable you still have 3 assignments but lose the 3 arithmetic but also have to add/remove the variable to from the stack. P. Todd Decker

JavaScript, by nature, stores all numbers as double-precision IEEE 754 floating point numbers. The 52 bits of the fractional portion is used to store integers. This results in 'maximum safe integer' of 253 - 1. Further complicating things is that JavaScript's bitwise operators only deal with the lowest 32 bits of JavaScript's 54-bit integers. So the bitwise approach will not work on big integers in JavaScript. Comment deleted Dean Bassett

Sorting functions. So you can write something simple like

``````// at this point in the sort, we know we must
// swap x with some other value
if a[x] < a[y] {
swap(&a[x], &a[y])
} else {
swap(&a[x], &a[z]) // a[x] and a[z] may be the same value
}
``````
Thread Dean Bassett

The function usually gets inlined anyway (depending on your compiler) and if it starts with `if x == y { return }` then it just compiles to `if x != y { /* swap x and y */ }`

In fact, might as well use a temporary variable at that point if you're expecting for compiler optimizations :shrug:. At that point they'd just become temporary registers and wouldn't have anything in memory, and a single `xchg` call

Thread Dustin King • Edited

To be a little bit sneaky, use part of the function itself as swap space. This would only work if that space could be after the return instruction.

In pseudo-C:

``````#define NOP {32 bits of assembly NOP instructions};

void swap(int* a, int* b){

*&yep = *a;
*a = *b;
*b = *&yep;

return;

yep:
NOP;
}
``````

This isn't thread-safe though, and a decent operating system might throw exceptions if you try to have executable code modify itself. Zuodian Hu

The `NOP`s don't actually give you any memory. Those `NOP`s are wherever the executable image was loaded in memory, and the variable `yep` is on the stack. Assuming your standard C memory model.

Thread Dustin King

C memory layout:

The function code itself is in the `text` segment. The variables for a particular invocation of the function are on the stack. Padding out the function with `NOP` creates space within the function, which I'm using as a variable. Basically I'm interpreting the "working memory" part of the post to mean "variables allocated on the stack". Now that I think of it, what I'm doing is basically a static variable, which (according to the link) C puts in the `initialized data` segment if you do it the right way, but then it would legitimately be a variable so I'd lose.

It's probably not a legit way to do things (and might be impossible if the text segment is read-only as the link says it might be), but people had already posted the legit ways.

Thread Nick Karnik

Thanks for that explanation. It's been a while since I've written C/C++, but this approach makes sense. I love the thought process of cleverly using that available memory, even if it doesn't work out. 👏👏👏 Zuodian Hu

The variable `yep` is declared within a function body without a `static` qualifier, which means it's what the C standard calls an automatic storage duration variable. This means its duration is between the curly braces, and most compilers will use a register or put it on the stack.

Being completely nitpicky here, but the variable `yep` is declared after its use and also without a type. I'm sure modern compilers wouldn't even let you do that.

Modern operating systems load the `text` segment into a virtual memory page marked as read-only. So yes, even if this compiles, it will generate a segfault on modern operating systems.

Thread Dustin King

`yep` isn't a variable, though, it's a label, representing an offset from the start of the function.

I agree compilers and OS's will tend to prevent this. I said as much before, and trying to create a proof of concept in assembly has born that out.

It wasn't a completely fruitless exercise though, as it was a chance to learn some assembly, which provided some insights about the challenge that I might make a post about. Basically, swapping using math might not actually be more memory-efficient (however you define that, and without the kind of cheating I've been talking about) than swapping using "a variable". Yaser Al-Najjar • Edited

Only two options, either using memory or CPU

1. Memory = third variable
``````temp = x
x = y
y = temp
``````
1. CPU = Swap algorithms

like XOR swap (bullet-proof solution)

``````x ^= y
y ^= x
x ^= y
``````

Or addition & subtraction (which is not bullet-proof when dealing with a 32-bit register that would need extra care with overflow)

``````x += y
y = x - y
x -= y
`````` Zuodian Hu • Edited

Very contrived, only works on ARM, not even acceptable by all C compilers, but you never constrained the problem that way!

``````void swap(int* a, int* b) {
__asm volatile (
"MOV R2, R1 \n"
"MOV R1, R0 \n"
"MOV R0, R2 \n"
);
}
`````` Zuodian Hu

I went to bed, and realized that my answer is wrong. Exchanging the values in register is completely invisible to the function caller. Here's the correct answer.

``````void swap(int* a, int* b) {
__asm volatile {
"LDR R2, [R0] \n"
"LDR R3, [R1] \n"
"STR R2, [R1] \n"
"STR R3, [R0] \n"
}
}
``````

Further, as `R0-R3` are all caller-save registers in the ARM ABI, the function body, excluding the function entry stack shenanigans, uses zero memory. yev

I've written my answer with C in mind, and it does explain how it works if you try the calculation by hand: onlinegdb.com/B1IY6hFK7

``````#include <stdio.h>

int main()
{
int a = 77;
int b = 42;
printf("a: %d, b: %d \n", a, b);

swap(&a, &b);
printf("after swap \n");
printf("a: %d, b: %d", a, b);

return 0;
}

void swap(int *a, int *b) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
``````

When both `a` and `b` has the same value: onlinegdb.com/r1WeypFF7

Result may vary depending on the language compiler, you might have to adjust the snippet according to your language's nuances. Sergiu Mureşan • Edited

I like defining one of these macros when swapping variables in C:

``````#define SWAP(A, B) A ^= B ^= A ^= B
#define SWAP(A, B) A = A - (B = (A = A + B) - B)
``````

The second one works on floating point numbers too. Ben Sinclair • Edited

Here's a warm-up interview question that I ask every candidate.

I've seen this question come up a lot, along with fizzbuzz or "write a sorting function" and I'm not sure it's useful anymore.

It's a purely academic problem that touches on several different concepts, none of which are going to be used by 99% of programmers these days.

Why do you ask this question? What do people's different answers tell you, or are you more looking for how people attempt to solve it (if they've not heard it before) or how quickly they regurgitate a stock solution (if they have?)

If I asked this, and someone answered quickly (they already know why the dead man in the desert is lying next to an unopened pack...) then I'd follow up with something asking when they had ever had to do this in real life, or even if they could come up with three examples of situations where it would be a useful thing to do in real life. If they couldn't, then I don't think I would have learned anything useful about them.

What do you get out of it? Nick Karnik

Good question! I used to ask this as a warm-up question back in the days at the beginning of an interview. (However, I've also used it in recent interviews after this post). I've never used this question to influence the outcome of the interview. It's merely conversational and a segue into academics to pique their interest into a deeper technical conversation.

If the candidate has heard the question before, I will follow up with a question around if the solution handles overflow when numbers are large and also dive a bit into perf. We may dive into when and if this solution might be needed for specific use-cases. The reality is that the compiler optimizes the code better when using a temporary variable.

If they haven't heard the question before, it gives me a chance to assess how they work through the problem and helps me find an appropriate role for them if the interview is somewhat generic. If they dislike that problem or find it difficult to solve it, they are most likely not going to enjoy working on hardware/firmware. Most people who solve it really enjoy the problem and in my experience have performed quite well on the job.

Recently, I observed that this question is part of the prep material online and most people have seen it, so there's not much value in asking it. I still do it for fun sometimes.

Anyway, I agree with your comment though. Ryan Westlund

(Posting before reading the other comments) I came up with two solutions, not sure if there's any reason either would be considered superior:

``````a = a + b
b = b - a
a = a + b
b = -b
``````
``````a = a + b
b = b + a
a = b - a
b = b - 2*a
`````` Kasey Speakman

This is your first step in becoming a Computer Scientist!

I think I must have skipped a few steps. The only occasion I've had to use such tricks is when playing Zachtronics games like TIS-100 or Shenzhen IO. I hope you are interviewing for embedded systems programmers. ;-) sivaiah587

# JAVA

int a=5;
int b=10;
a=a+b;
b=a-b;
a=a-b;
System.out.println(a);//10
System.out.println(b);//5
String s1="java1";
String s2="java2";
s1=s1+s2;
s2=s1.substring(0,(s1.length()-s2.length()));
s1=s1.substring(s2.length());
System.out.println(s1);//java2
System.out.println(s2);//java1 Senthil Kumar

Here's my code snippet showing how we can swap two numbers without using temporary variable at coderseditor.com/?id=185

using System;

namespace CodeSample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Swap Number Sample");
int number1, number2;
Console.WriteLine("Enter the First Number : ");
number1 = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the Second Number : ");
number2 = int.Parse(Console.ReadLine());
number1 = number1 - number2;
number2 = number1 + number2;
number1 = number2 - number1;
Console.WriteLine("First Number is " + number1);
Console.WriteLine("Second Number is " + number2);
Console.Read();
}
}
} Comment deleted