#include #include /*************************************************** * Swapping without a temporary variable * * Normally, to swap two values we would use a * temporary variable: * * std::uint64_t tmp{ m }; * m = n; * n = tmp; * * There is, however, an interesting way to swap two * unsigned integers using only the bitwise XOR * operator. * * Recall that XOR has the properties * * x ^ x == 0 * x ^ 0 == x. * * XOR is also associative and commutative: * * (x ^ y) ^ z == x ^ (y ^ z) * * and * * x ^ y == y ^ x. * * These properties allow us to recover two original * values after XORing them together. * * * THE XOR SWAP * * Suppose initially * * m == a * n == b. * * First calculate * * m ^= n; * * so that * * m == a ^ b * n == b. * * Next calculate * * n ^= m; * * giving * * n == b ^ (a ^ b) * == a ^ (b ^ b) * == a ^ 0 * == a. * * Thus, n now contains the original value of m. * * Finally, calculate * * m ^= n; * * giving * * m == (a ^ b) ^ a * == (a ^ a) ^ b * == 0 ^ b * == b. * * Thus, m now contains the original value of n. * * The values have been swapped without using a * temporary variable. * * * AN IMPORTANT WARNING * * This algorithm assumes that m and n refer to * different objects. * * If we were to call * * swap( a, a ); * * then the first operation would calculate * * a ^= a; * * which sets a to zero. * * Thus, this XOR swap should be regarded primarily * as an interesting application of bitwise XOR, * rather than as a recommended way to swap values * in C++ programs. ***************************************************/ // Function declarations int main(); void swap( std::uint64_t &m, std::uint64_t &n ); // Function definitions int main() { std::uint64_t a{ 53215362 }; std::uint64_t b{ 7789898 }; std::cout << "Before: " << a << ", " << b << std::endl; swap( a, b ); std::cout << "After: " << a << ", " << b << std::endl; return 0; } /*************************************************** * swap * * Swaps two 64-bit unsigned integers using bitwise * XOR and without using a temporary variable. * * The two arguments must refer to different objects. ***************************************************/ void swap( std::uint64_t &m, std::uint64_t &n ) { m ^= n; n ^= m; m ^= n; } /*************************************************** * In modern C++ * * You are not expected to use this in this exercise, * but in an actual C++ program you should normally * use std::swap rather than the XOR technique above. * * After including , we can write * * std::swap( m, n ); * * This clearly states what we want to do, works for * many types other than integers, and does not have * the same problem when both arguments refer to the * same object. * * The purpose of the XOR version in this exercise * is to explore the properties of the bitwise XOR * operator. ***************************************************/