--- author: "Devoalda" authorEmoji: 🐺 title: "Rust - Swap Numbers" date: 2023-04-11T09:12:58+08:00 description: Swapping 2 numbers without a temp variable draft: false hideToc: false enableToc: true enableTocContent: true tocPosition: inner tocLevels: ["h1", "h2", "h3"] tags: - Algorithm - rust series: - rust categories: - rust image: libraries: - mathjax math: true --- # Introduction This is a number swapping operation without using a temp variable written in Rust. A swap with a temp variable would look like this: ```rust fn swap_with_temp(mut a:i32, mut b:i32) -> (i32, i32) { let temp = a; a = b; b = temp; (a, b) } ``` This creates another temp variable to contain either values in `a` or `b`, followed by doing the actual swap, and reassigning the value in the temp variable to the second variable. This causes a slight waste of space as a temp variable of greater or equal size to the larger of the 2 variables is needed to do the swap. A space efficient is to use mathematical operations `+`, `-`, `*`, `/` or Bitwise `XOR` to do the swap. # Code ```rust fn main() { let a:i32 = 20; let b:i32 = 10; println!("Before swap a = {} and b = {}", a, b); let mut result = swap(a, b); println!("After swap1: a = {} and b = {}", result.0, result.1); result = swap2(result.0, result.1); println!("After swap2: a = {} and b = {}", result.0, result.1); result = match result{ (0, 0) => (a, b), (0, _) => (a, b), (_, 0) => (a, b), _ => swap3(result.0, result.1) }; println!("After swap3: a = {} and b = {}", result.0, result.1); result = swap_with_temp(result.0, result.1); println!("After swap_with_temp: a = {} and b = {}", result.0, result.1); } fn swap(mut a: i32, mut b: i32) -> (i32, i32) { a = a + b; b = a - b; a = a - b; (a, b) } fn swap2(mut a:i32, mut b:i32) -> (i32, i32) { a = a ^ b; // A XOR B b = a ^ b; // A XOR B XOR B = A a = a ^ b; // A XOR B XOR A = B (a, b) } fn swap3(mut a:i32, mut b:i32) -> (i32, i32) { a = a * b; b = a / b; a = a / b; (a, b) } fn swap_with_temp(mut a:i32, mut b:i32) -> (i32, i32) { let temp = a; a = b; b = temp; (a, b) } ``` ```bash # Output Before swap a = 10 and b = 20 After swap1: a = 20 and b = 10 After swap2: a = 10 and b = 20 After swap3: a = 20 and b = 10 After swap_with_temp: a = 10 and b = 20 ``` The above uses multiple methods to do a swap between 2 variables. However, this is not foolproof. ## Potential Issues ### Overflow If either of the variables are larger than the specified type (`i32`), there will be an **overflow** of variables: ```rust fn main() { let a:i32 = 1000000000; let b:i32 = 2000000000; } ``` ```python Before swap a = 1000000000 and b = 2000000000 thread 'main' panicked at 'attempt to add with overflow', src/main.rs:17:9 ``` ### Divide by zero `swap3` uses multiplication and division for the swap. Exception handling is required to prevent a `divide by zero` error, if either of `a` or `b` is zero. ```rust let a:i32 = 0; let b:i32 = 10; ``` ```python thread 'main' panicked at 'attempt to divide by zero', src/main.rs:33:9 ``` A `match` is done to prevent the use of the function if either numbers are zero: ```rust result = match result{ (0, 0) => (a, b), (0, _) => (a, b), (_, 0) => (a, b), _ => swap3(result.0, result.1) }; println!("After swap3: a = {} and b = {}", result.0, result.1); ```