Cuando queremos hacer que una variable a sea igual a una variable b y viceversa (intercambiar los valores), lo primero que se viene a la mente, es utilizar una variable auxiliar, como en este ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Aunque puede que queramos (o que nos pidan) hacerlo sin variable temporal, podemos hacer un intercambiador con sumas y restas:
1 2 3 4 5 6 | void intercambia2(int *x, int *y) { *x=*x+*y; /* x=x+y */ *y=*x-*y; /* y=x-y */ *x=*x-*y; /* x=x-y */ } |
Y con las propiedades de la operación XOR también podemos jugar:
1 2 3 4 5 6 | void intercambia3(int *x, int *y) { *x ^= *y; /* x = x xor y */ *y ^= *x; /* y = y xor x */ *x ^= *y; /* x = x xor y */ } |
Pero lo bueno de estos dos últimos métodos es que los podemos utilizar desde macros de preprocesador, y con eso nuestro código se ejecutará mucho más rápido:
1 2 3 4 5 6 7 8 9 |
Para ver lo rápido que se ejecuta, he hecho el programa intercambiando continuamente en un bucle for de unos 300000000 (trescientos millones) de iteraciones lo siguiente:
Para la macro de preprocesador interc(a,b),
gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./interc
a=-50 b=40
a=-50 b=40real 0m8.027s
user 0m7.461s
sys 0m0.022s
Para intercambia(a,b) (con variable auxiliar):
gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./intvaux
a=-50 b=40
a=-50 b=40real 0m8.691s
user 0m7.058s
sys 0m0.022s
Para intercambia2(a,b), con sumas y restas:
gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./intsyr
a=-50 b=40
a=-50 b=40real 0m12.331s
user 0m10.508s
sys 0m0.024s
Para intercambia3(a,b) con xor:
gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./intxor
a=-50 b=40
a=-50 b=40real 0m11.882s
user 0m10.516s
sys 0m0.031s
Por lo tanto vemos, que el método de la variable auxiliar es bastante rápido, mucho más que haciendo sumas y restas y xor (por lo tanto estos métodos no sirven de mucho, sobre todo ahora, que la memoria es barata), aunque, con las sumas y restas nos acercamos en tiempo al método de la variable auxiliar cuando lo hacemos desde una macro.
Ahora bien, es una cosa un poco sucia, pero es un buen experimento: crear una variable global c, y una macro que haga el intercambio ayudándose de la variable auxiliar c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Con éste método, obtenemos estos tiempos:
gaspy@XiKiTiN ~/proyectos/poesiabinaria $ time ./inter
a=-50 b=40
a=-50 b=40real 0m3.087s
user 0m2.901s
sys 0m0.005s
Bastante menos 🙂 De todas formas estos tiempos son aproximados.
Pingback: Bitacoras.com /
Pingback: Binary prose » Swapping variable values (examples in C) /
Pingback: Operador coma – Poesía Binaria /
Pingback: Operator comma. How to incorporate it into our day-to-day life with many examples in C | Study Of Programming /