miércoles, 8 de mayo de 2013

Un ejemplo usando operadores para manejo de bits

Éste programa usa la función getbits (sección 2.9 de El Lenguaje de Programación C, de Kernighan y Ritchie). La razón para ponerlo aquí es que no es claro a primera vista, al menos para mí, lo que esa función hace. En la sección 2.9 se estudian los operadores binarios y getbits hace uso de &, el and de bits; <<, corrimiento a la izquierda; >>, corrimiento a la derecha y ~, complemento a uno, para hacer lo siguiente:
"regresa el campo de n bits de x (ajustado a la derecha) que principia en la posición p. Se supone que la posición del bit 0 está en el borde derecho y que n y p son valores positivos adecuados. Por ejemplo, getbits(x,4,3) regresa los tres bits que están en la posición 4, 3 y 2 ajustados a la derecha."

No soy el único que encuentra difícil la redacción (la original, en inglés) del libro de Kernighan y Ritchie. He encontrado varias páginas y foros en los que la gente se pregunta qué quisieron decir en tal o caul parte. Afortunadamente, aquí se puede entender sin ambigûedades.
Vamos a suponer que las variables son éstas: x = 179, p = 4 y n = 3. Para hacer ésto más fácil, la representación binaria de 179 es la siguiente:

Representación binaria de 179, en 10 bits.
Lo que hace nuestra función es mostrar dejar únicamente los 3 bits que comienzan a partir de la posición 4 (la posición extrema derecha es la 0). Éstos bits son 1 0 0, y deben aparecer corridos hacia la derecha. Todos los demás bits deben estar establecidos en 0.
El número 179 después de aplicar getbits.
El corazón del programa es, desde luego, la instrucción

return ((x >> (p+1-n)) & ~(~0 << n));

Ésta línea se divide en dos partes, separadas por el operador &. La instrucción x >> (p+1-n) corre hacia la derecha (4+1-3 = 2) bits. Esto es, se eliminan los bits 0 y 1 (ambos con 1), que deja el número binario 0000101100.
~(~0 << n) crea una máscara de bits. ~0 genera el binario 1111111111 y ~0 << n, con n = 3, corre hacia la izquierda el primer bit y llena los espacios con 0. Se produce entonces el número binario 1111111000. Finalmente, ~(~0 << n) crea el binario 0000000111. Esta es la máscara. Aplicando el operador & a 0000101100 y 0000000111 produce 0000000100. Este número es 4. Es precisamente lo que se obtiene al ejecutar el programa
/*++++++++++++++++++++++++++++++++++++++++++++
 * "regresa el campo de n bits de x (ajustado *
 * a la derecha) que principia en la posicion *
 * p. Se supone que la posicion del bit 0     *
 * esta en el borde derecho y que n y p son   *
 * valores positivos adecuados" Kernighan-    *
 * Ritchie                                    *
 *+++++++++++++++++++++++++++++++++++++++++++*/
#include 

///////////////////////////////////////
// FUNCION GETBITS
// ////////////////////////////////////

unsigned getbits(unsigned x, int p, int n)
{ /* Abre getbits*/
 
return ((x >> (p+1-n)) & ~(~0 << n));

} /*Cierra getbits*/

////////////////////////////////////////
//FUNCION MAIN
////////////////////////////////////////

int main()
{ /* Abre main*/

unsigned numero;
int a, b;

printf("\nIntroduzca un entero sin signo: ");
scanf("%d", &numero);

printf("\nIntroduzca el numero de bits a mostrar: ");
scanf("%d", &b);

printf("\nIntroduzca el numero de bit a partir del cual se mostraran: ");
scanf("%d", &a);

printf("El numero es: %d\n", getbits(numero,a,b));

return 0;
}/*Cierra main*/
Aquí la ejecución

[hernandez@localhost Programas]$ ./a.out 

Introduzca un entero sin signo: 179

Introduzca el numero de bits a mostrar: 3

Introduzca el numero de bit a partir del cual se mostraran: 4
El numero es: 4

No hay comentarios:

Publicar un comentario

Related Posts Plugin for WordPress, Blogger...