Los que estudiaron programación indudablemente se encontraron con el problema de swapear dos variables, es decir, intercambiar su valor, y los profesores indudablemente mostraban la resolución:
1 2 3 4 5 6 | void Swap (ref int a, ref int b) { int swapTemporal = a; a = b; b = swapTemporal; } |
Donde se usaba una variable temporal para no perder el valor de a cuando se le asigna el valor de b, para posteriormente asignárselo a b. Algunos tal ves se hayan encontrado la resolución alternativa, usando XOR sin variable temporal:
1 2 3 4 5 6 | void Swap (ref int a, ref int b) { a = a ^ b; b = a ^ b; a = a ^ b; } |
Y quedaron sorprendidos por que ciertamente funciona.
¿Pero, por que?
Empezamos definiendo rápidamente, XOR es un OR exclusivo, lo que significa que es un operador binario que nos da como resultado un 1 solamente si uno de los dos (pero no ambos) operandos es igualmente 1, es decir, la siguiente tabla de verdad:
_________________ | a | b | a ^ b | ----------------- | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | | 1 | 1 | 0 | -----------------
Dado esto podemos definir un par de axiomas:
a ^ a = 0 a ^ 0 = a
es decir:
- Si ambos operandos son iguales en un XOR el resultado es invariablemente cero
- Si un operando es igual a cero en un XOR el resultado es invariablemente el valor del otro operando
Y estos dos axiomas son lo único que necesitamos para comprobar que el primer y segundo código son equivalentes:
a’ = a ^ b //Es a prima para evitar confundir la variable con el valor original de a
b’ = a’ ^ b
Si sutituimos el valor de a’ tenemos:
b’ = (a ^ b) ^ b
b ^ b = 0 por nuestro primer axioma, por lo que nos queda:
b’ = a ^ 0
a ^ 0 = a por nuestro segundo axioma, por lo que tenemos
b’ = aa’ = a’ ^ b’ //Si sustituimos los valores de a’ y b’ tenemos:
a’ = (a ^ b) ^ a
a ^ a = 0 por nuestro primer axioma, por lo que nos queda:
a’ = b ^ 0
b ^ 0 = b por nuestro segundo axioma, por lo que tenemos
a’ = bAsi, al finl de las tres operaciones a’ tiene el valor original de b, y b’ el valor original de a.
Q.E.D. \o/
Como ven la demostración es trivial y seguramente un overkill, pero te puede matar 5 minutos de aburrimiento :p. Nos vemos en la siguiente entrega cuando demuestre que el negro es blanco, claro, al menos que muera antes en un crucero de zebras.