Programación utilizando operadores a nivel de bits Unidad III – Conceptos Avanzados de Programación Programación I
Programación utilizando operadores a nivel de bits Contenido Esta lección abarca los siguientes temas: Operadores a nivel de bits Enmascaramiento Campos de bits
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Las computadoras representan todos los datos internamente como secuencia de bits. Una secuencia de 8 bits forman un byte que es la unidad estándar de almacenamiento. C puede manejar a nivel de bits (char, short, int y long). No manipula los punto flotantes.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Las operaciones a nivel de bits se refieren a la comprobación, asignación o desplazamiento de los bits reales que componen un byte o una palabra de memoria, que corresponden a los tipos estándar de C char, short, int y long. Los enteros no signados (unsigned) son utilizados normalmente con los operadores a nivel de bits. Las manipulaciones a nivel de bits son dependientes de la máquina.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits AND (&) OR inclusivo (|) OR exclusivo (^) Complemento (~) Operadores Lógicos Operadores de Desplazamiento Desplazamiento a la izquierda (<<) Desplazamiento a la derecha (>>)
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits OperadorUsoOperación &Operando & Operando Realiza una operación AND lógico entre los dos operandos |Operando | Operando Realiza una operación OR lógica entre los dos operandos ^Operando ^ Operando Realiza una operación lógica OR Exclusiva entre los dos operandos ~~Operando Complementario del operando (unario) Operadores Lógicos
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits AND (&) Los bits se establecen a 1 si los bits en ambos operandos son 1. OR inclusivo (|) Los bits se establecen a 1 si por lo menos uno de los bits correspondientes en los dos operandos es 1. OR exclusivo (^) Los bits se establecen a 1 si solo uno de los bits correspondientes en los dos operandos es 1. Complemento (~) Todos los bits 0 se definen a 1 y todos los 1 se definen a 0. Operadores Lógicos
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Operadores Lógicos COMPLEMENTO AND OROR EXCLUSIVO
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ char letra1, letra26, res; letra1 = ‘A’; /* 65 */ letra26 = ‘Z’; /* 90 */ res = letra1 & letra26; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } letra1 letra letra1 & letra26 M E M O R I A P A N T A L L A y Entero= 64 AND (&) Los bits se establecen a 1 si los bits en ambos operandos son 1.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ char letra1, letra26, res; letra1 = ‘A’; /* 65 */ letra26 = ‘Z’; /* 90 */ res = letra1 | letra26; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } letra1 letra letra1 | letra26 M E M O R I A P A N T A L L A Caracter= [ y Entero= 91 OR inclusivo (|) Los bits se establecen a 1 si por lo menos uno de los bits correspondientes en los dos operandos es 1.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ char letra1, letra26, res; letra1 = ‘A’; /* 65 */ letra26 = ‘Z’; /* 90 */ res = letra1 ^ letra26; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } letra1 letra letra1 ^ letra26 M E M O R I A P A N T A L L A Caracter= ← y Entero= 27 OR exclusivo (^) Los bits se establecen a 1 si solo uno de los bits correspondientes en los dos operandos es 1.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ char letra, res; letra = ‘Z’; /* 90 */ res = ~ letra; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } letra ~letra En realidad el resultado es 165(Ñ), pero como la capacidad de almacenamiento de 8 bits es =255 con rango [-128,127] entonces calcula =37 y luego = -91 M E M O R I A P A N T A L L A Caracter= Ñ y Entero= -91 OR exclusivo (~) Todos los bits 0 se definen a 1 y todos los 1 se definen a 0.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ unsigned char letra, res; letra = ‘Z’; /* 90 */ res = ~ letra; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } letra ~letra El rango de almacenamiento de res será [0,255]. M E M O R I A P A N T A L L A Caracter= Ñ y Entero= 165 OR exclusivo (~) Todos los bits 0 se definen a 1 y todos los 1 se definen a 0.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Operadores de Desplazamiento OperadorUsoOperación >> Operando >> Despl Desplaza bits del Operando hacia la derecha las posiciones indicadas por Despl (con signo) y rellena con cero a la izquierda. <<Operando << Despl Desplaza bits del Operando hacia la izquierda las posiciones indicadas por Despl (con signo) y rellena con cero a la derecha.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ char letra, res; letra = ‘Z’; /* 90 */ res = letra >> 3; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } Desplazamiento a la derecha (>>) Desplaza los bits del Operando hacia la derecha las posiciones indicadas por Despl (con signo) y rellena con cero a la izquierda letra letra >> 3 M E M O R I A P A N T A L L A Caracter= ♂ y Entero= 11 bits perdidos bits de relleno
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits void main (){ char letra, res; letra = ‘Z’; /* 90 */ res = letra << 3; printf(“Caracter= %c y Entero= %d”,res, res); getch(); } Desplazamiento a la izquierda (<<) Desplaza los bits del Operando hacia la izquierdalas posiciones indicadas por Despl (con signo) y rellena con cero a la derecha letra letra << 3 M E M O R I A P A N T A L L A Caracter= ð y Entero= 208 bits perdidos bits de relleno
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Operadores de Desplazamiento En las operaciones con desplazamiento de bits descritas, se toma en cuenta el signo, por ejemplo, asumiendo que el operando tiene todos los bits en 1: Desplazamiento a la Derecha: 128 >> 1 retorna 128 / 2 1 = >> 4 retorna 256 / 2 4 = >> 4 retorna -256 / 2 4 = -16 Desplazamiento a la Izquierda: 128 << 1 retorna 128 * 21 = << 2 retorna 16 * 22 = << 2 retorna -16 *22 = -64
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Enmascaramiento El enmascaramiento se utiliza para ocultar información, esto se hace mediante máscaras que se encargan de esconder (disfrazar) algunos bits en un valor, mientras otros bits se seleccionan. El enmascaramiento se logra con los operadores lógicos &, | y ^. Para cada operador el tipo de enmascaramiento funciona de un modo distinto.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Enmascaramiento Supongamos que en un dato entero corto (por ejemplo, el código de un empleado) se codificó información, de tal manera que los bits 4 y 5 representan el estado civil, con las siguientes combinaciones: Los bits 4 y 5 son 2 bits y cada bit tiene 2 posibles valores 0/1. Entonces, hay 2 #bits combinaciones. Esto es, 2 2 = 4 combinaciones. Éstas son: Bits 5 4 Ahora supongamos que cada combinación representa un estado civil, por ejemplo: Soltero Casado Divorciado Viudo
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Enmascaramiento Ahora veamos, el resultado en decimal que obtenemos con esas combinaciones en los bits 4 y Bits 5 4 = (0)*2 4 + (0)* > 0 = (0)*2 4 + (1)* > 16 = (1)*2 4 + (0)* > 32 = (1)*2 4 + (1)* > 48
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Enmascaramiento = soltero > 0 = casado -----> 16 = divorciado --->32 = viudo > Ahora veamos cuatro códigos de empleados (enteros cortos: 67, 4115, 544 y 2096) con la información codificada: 67 = 4115 = 544 = 2096 =
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Enmascaramiento de la información void main (){ short int codigo=64, mascara, op; /* */ printf(“1. Soltero\n”); printf(“2. Casado\n”); printf(“3. Divorciado\n”); printf(“4. Viudo\n”); printf(“Opcion: ”); scanf(“%d”,&op); switch(op){ case 1: { mascara=0; break;} case 2: { mascara=16; break;} case 3: { mascara=32; break;} case 4: { mascara=48; break;} } codigo=codigo | mascara; printf(“Su codigo es: %d\n”, codigo); getch(); } codigo mascara codigo|mascara M E M O R I A P A N T A L L A
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Des-Enmascaramiento con operador &: Copia los bits indicados del patrón original y el resto de bits los anula ó hace cero. La máscara debe tener 1 en el bit que se desea copiar y 0 si el bit se desea anular.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Des-Enmascaramiento con operador &: void main (){ short int codigo, mascara, res; codigo = 80; /* */ mascara = 48; /* */ res = codigo & mascara; printf(“Resultado = %d\n”, res); getch(); } codigo mascara codigo&mascara M E M O R I A P A N T A L L A Resultado = 16 switch(res){ case 0: printf(“Es soltero\n”); break; case 16: printf(“Es casado\n”); break; case 32: printf(“Es divorciado\n”); break; case 48: printf(“Es viudo\n”); break; } Es casado
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Des-Enmascaramiento con operador | (OR inclusiva): Copia los bits indicados del patrón original y el resto de bits los hace uno. La máscara debe tener 0 en el bit que se desea copiar y 1 si el bit se desea hacer 1. void main (){ short int codigo, mascara, res; codigo = 83; mascara = 48 /* */ res = codigo | mascara; printf(“Resultado = %d”, res); getch(); } codigo mascara codigo|mascara M E M O R I A P A N T A L L A Resultado = 223
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Des-Enmascaramiento con operador ^ (OR exclusiva): Copia los bits indicados del patrón original y el resto de bits los invierte. La máscara debe tener 0 en el bit que se desea copiar y 1 si el bit se desea invertir. void main (){ short int codigo, mascara, res; codigo = 83; mascara = 48 /* */ res = codigo ^ mascara; printf(“Resultado = %d”, res); getch(); } codigo mascara codigo|mascara M E M O R I A P A N T A L L A Resultado = 223
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Programa para visualizar bits #include void mostrarBits(unsigned); int main() { unsigned x; printf("Introduzca un entero sin signo: "); scanf("%u", &x); mostrarBits(x); return 0; } void mostrarBits (unsigned valor) { unsigned c, mascara = 1<<31; printf("%7u = ", valor); for (c=1;c<=32;c++) { putchar(valor & mascara ? '1': '0'); valor <<=1; if (c% 8 ==0) putchar(' '); } putchar('\n'); }
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Cada operador a nivel de bits (a excepción del operador de complemento) tiene un operador de asignación correspondiente: &= |= ^= <<= >>= Operador de asignación AND a nivel de bits Operador de asignación OR inclusivo a nivel de bits Operador de asignación OR exclusivo a nivel de bits Operador de asignación de desplazamiento a la izquierda Operador de asignación de desplazamiento a la derecha
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Campos de bits struct CamposBits { unsigned edad : 4; unsigned peso : 2; unsigned color : 1; }; Máquina con palabra de 4 bytes:... edad peso color Lenguaje C/C++ proporciona la capacidad de especificar o definir el número de bits en el cual se almacena un miembro unsigned o int de una estructura o de una unión. Los miembros de campos de bits deben ser declarados como int o unsigned.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Campos de bits struct CamposBits { unsigned edad : 4; unsigned : 0; unsigned color : 1; }; Máquina con palabra de 4 bytes: Un campo de bits sin nombre con ancho cero, se utiliza para alinear el siguiente campo de bits en el límite de la nueva unidad de almacenamiento.... edad color...
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Campos de bits Los campos de bits son accedidos del mismo modo que los miembros de otras estructuras y pueden aparecer en expresiones aritméticas como cantidades enteras sin signo. Sin embargo, hay restricciones en su uso, como lo son: No se permiten arreglos de campos de bits. El operador & dirección no se puede aplicar a un campo de bits. Un puntero no puede acceder a un campo de bits. Una función no puede devolver un campo de bits.
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Ejemplo de Campos de Bits: Máquina con palabra de 4 bytes:... edad carrera sexo struct Estudiante { unsigned edad : 7; /*Entre 0 y 70 años*/ unsigned : 1; unsigned carrera : 4; /*Existen 11 carreras*/ unsigned : 4; unsigned sexo : 1; };
Programación utilizando operadores a nivel de bits Operadores a Nivel de Bits Ejemplo de Campos de Bits: #include “stdio.h” #include “conio.h” typedef struct { /* [0,70] */ unsigned edad : 7; unsigned : 1; /* 11 carreras */ unsigned carrera : 4; unsigned : 4; unsigned sexo : 1; } Estudiante; printf(“\nCarrera: 0 ->Informatica”); printf(“\n 1 ->Electrónica”); printf(“\n 6 ->Ambiental\n”); scanf(“%d”, &carrera); vector[i].carrera=carrera; printf(“\nIngrese el sexo F/M: ”); s=toupper(getche()); vector[i].sexo = (s==‘F’)? 0: 1; fflush(stdin); } for (i=0; i<5; i++) { printf(“\nEdad: %d”, vector[i].edad); printf(“\nCarrera: %d”, vector[i].carrera); printf(“\nSexo: %d”, vector[i].sexo); } getch(); } void main() { Estudiante vector[5]; int i, edad, carrera; char s; for (i=0; i<5; i++) { printf(“\nIngrese la edad: ”); scanf(“%d”, &edad); vector[i].edad=edad;