manejo de bits

Post on 23-Jan-2018

471 Views

Category:

Education

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

MANEJO DE BITS

INTRODUCCIÓN

Una computadora sin software sólo tiene

capacidades para hacer operaciones aritméticas

simples (sumas, restas, multiplicación, etc.)

El software se vale de estas simples operaciones

para crear interfaces como las que vemos en los

modernos sistemas operativos.

Todos los lenguajes, desde los más altos como

“PHP”, hasta los más bajos como “Ensamblador”,

pasan por binario; cada vez que se mueve el ratón

se invocan procesamiento de datos binarios.

INTRODUCCIÓN

Una de las razones por las que C y C++ se han

hecho tan populares es por que el lenguaje ofrece

muchos operadores de manipulación de bits a bajo

nivel.

Los operadores de manipulación de bits (bitwise)

ejecutan operaciones lógicas sobre cada uno de

los bits de los operandos.

Estas operaciones son comparables en eficiencia y

en velocidad a sus equivalentes en lenguaje

ensamblador.

INTRODUCCIÓN

Cada operador de manipulación de bits realiza una

operación lógica, bit a bit, sobre datos internos.

Los operadores de manipulación de bits se aplican

sólo a variables y constantes char, int y long, y no a

datos con punto flotante.

Dado que los números binarios constan de 1’s y 0’s

(bits) estos 1 y 0 se manipulan para producir el

resultado deseado para cada uno de los

operadores.

OPERADORES QUE VEREMOS

"&“

"|“

"^“

"~“

"<<"

">>"

& OPERADOR AND & operador AND de bits (sólo aplicables a variables de

tipo entero)

El operador & (no confundir con el operador lógico &&) es un

operador lógico a nivel de bits.

Compara un par de cadenas de bits por bit; el resultado para

cada comparación es 1 si los bits comparados son ambos 1, y

0 en otro caso.

0 & 0 = 0

0 & 1 = 0

1 & 0 = 0

1 & 1 = 1

¿CUÁL ES EL RESULTADO DE APLICAR EL

OPERADOR AND?

1 1 0 1 0 1

0 1 1 0 0 1

OPERADOR &

Con este operador & se puede ocultar un conjunto

de bits que no son relevantes en determinada

situación.

Esto constituye una máscara de bits.

Consideremos un pequeño problema y elaborar

una solución:

OPERADOR &

En un ciclo controlado por la variable TAMANO, es

necesario imprimir el valor del contador sólo desde

0 hasta 15, y comenzar después en 0, aún cuando

TAMANO se siga incrementando.

PROCEDIMIENTO DE EJEMPLO ANDvoid operadorAND(void){

/*+++++++++++++++++++++++++++++++++++++++*

*Este procedimiento recibe un par de numeros *

*e imprime el resultado de aplicarles el *

*operador binario & *

*+++++++++++++++++++++++++++++++++++++++*/

int x;

int y;

int res;

cout << "\nEste programa hace uso del operador binario &\n";

cout << "\nIntroduzca un entero: ";

cin >> x;

cout << "\nIntroduzca un segundo entero: ";

cin >> y;

res = x&y;

cout << x <<" " << y << " " << res;

}

USO PRÁCTICO

Tablas de estatus o permisos – se tiene un campo

“permisos” en la base de datos que corresponde a

un campo tipo integer, donde el valor1 = lectura

2 = escritura Cada valor corresponde

4 = ejecución a un bit encendido

8 = otro permiso

Si se lee 3 significa lectura y

escritura.

6 = escritura y ejecución

USO PRÁCTICO

Si se requiere saber si un usuario posee permisos

de escritura, se aplica máscara AND con valor 2.

EJEMPLO DE USO PRÁCTICO

Investiga el valor binario de 1, 2 y 4

Recuerda que 1 significa lectura, 2 significa

escritura y 4 significa ejecución.

Para saber qué permisos tiene un usuario, se

aplica el permiso que uno busca con un operador

AND y el permiso que tiene el usuario.

¿QUÉ PUEDE HACER CADA USUARIO?

Permisos lectura 0 0 0 0 0 0 0 1

Permisos escritura 0 0 0 0 0 0 1 0

Permisos ejecución 0 0 0 0 0 1 0 0

Permisos usuarioA 0 0 0 0 0 1 1 0

Permisos usuarioB 0 0 0 0 0 0 1 1

Permisos usuarioC 0 0 0 0 1 1 1 1

PROCEDIMIENTO DE EJEMPLO MÁSCARA/*+++++++++++++++++++++++++++++++++++++++++++++

* Este procedimiento imprime ciclicamente valores +

* de una variable por debajo de un limite, +

* por medio de una mascara de bits. +

* +++++++++++++++++++++++++++++++++++++++++++*/

#define TAMANO 200

#define LIMITE 15

//LIMITE funciona como una máscara que oculta los bits a la izquierda de

//último 1 a la izquierda.

void MASCARA (void){

int i = 0, mascara;

for (i = 0; i < TAMANO; i++)

{

mascara = i & LIMITE;

cout << mascara << "\n";

}

}

07

/09

/201

5

15

Mtl. L

ou

rdes C

ah

uic

h

| OR INCLUSIVO (PALABRA CLAVE BITOR)

Este operador binario tiene un funcionamiento parecido a los anteriores (AND y XOR), salvo que en este caso el resultado es 1 si alguno de ellos está a 1. En caso contrario devuelve 0 (ver ejemplo).

Ejemplo:

int x = 10, y = 20;

int z = x | y; // equivale a:

int z = x bitor y;

Según el enunciado, el operador | aplicado entre los valores 6 y 13 resultaría:

6 == 0000 0110

13 == 0000 1101

------------------

0000 1111 == 15

^ XOR OR EXCLUSIVO (PALABRA CLAVE

XOR)

El funcionamiento de este operador binario es parecido al AND lógico , salvo que en este caso el resultado es 1 si ambos bits son complementarios (uno es 0 y el otro 1). En caso contrario devuelve 0.

Ejemplo:

int x = 10, y = 20;

int z = x ^ y; // equivale a: int z = x xor y;

Según el enunciado, el operador ^ aplicado entre los valores 7 y -2 resultaría:

7 == 0000 0111

-2 == 1111 1110

------------------

1111 1001 == -7

~ COMPLEMENTO A UNO

(PALABRA CLAVE COMPL)

Este operador unitario invierte cada bit del operando; 0

es convertido en 1 y viceversa.

La representación binaria de los complementos a uno de

los decimales 0, 1 y 2 son los que se expresan (para

simplificar los representamos como un octeto):

0 == 0000 0000 ~ 0 == 1111 1111

1 == 0000 0001 ~ 1 == 1111 1110

2 == 0000 0010 ~ 2 == 1111 1101

PROCEDIMIENTO DE EJEMPLOvoid complementoAuno(void){

/*+++++++++++++++++++++++++++++++++++++++++++++

* Este procedimiento cambia un numero sin sigo a +

* su complemento a uno a nivel de bits +

* ++++++++++++++++++++++++++++++++++++++++++*/

short signed cero = 0, uno = 1, dos = 2;

cout << "~0 == " << ~cero << endl;

cout << "~1 == " << ~uno << endl;

cout << "~2 == " << ~dos << endl;

}

<< DESPLAZAMIENTO A IZQUIERDA

Este operador binario realiza un desplazamiento de

bits a la izquierda. El bit más significativo (más a la

izquierda) se pierde, y se le asigna un 0 al menos

significativo (el de la derecha). El operando

derecho indica el número de desplazamientos que

se realizarán.

Recuerde que los desplazamientos no son

rotaciones; los bits que salen por la izquierda se

pierden, los que entran por la derecha se rellenan

con ceros. Este tipo de desplazamientos se

denominan lógicos en contraposición a los cíclicos

o rotacionales.

<< DESPLAZAMIENTO A IZQUIERDA

unsigned long x = 10;

int y = 2;

unsigned long z = x << y;

Según las premisas anteriores, los

desplazamientos izquierda de valor unitario

aplicados sobre los números 0, 1, 2 y -3, producen

los siguientes resultados:

0 == 0000 0000 0 << 1 == 0000 0000 == 0

1 == 0000 0001 1 << 1 == 0000 0010 == 2

2 == 0000 0010 2 << 1 == 0000 0100 == 4

-3 == 1111 1101 -3 << 1 == 1111 1010 == - 6

PROCEDIMIENTO DE EJEMPLO

void desplazamientoAIzquierda(void){

int x = 1;

// Los operadores de bits solo se aplican a variables unsigned

cout << "\nEl tamanio de una variable int es: " << sizeof(int) << endl;

cout << "\nEl valor inicial de x: " << x << endl;

for (unsigned i = 1; i <= 8; i++)

{

unsigned desplazado = x << i;

cout << "\nEl numero: " << desplazado << endl;

}

cout << "\nEl valor final de x: " << x << endl;

}

>> DESPLAZAMIENTO A DERECHA

Igual que el desplazamiento a la izquierda, pero el

desplazamiento de bits es, obviamente, a la

derecha.

Sintaxis

expr-desplazada >> expr-desplazamiento

0 == 0000 0000 0 >> 1 == 0000 0000 == 0

2 == 0000 0010 2 >> 1 == 0000 0001 == 1

-2 == 1111 1110 -2 >> 1 == 1111 1111 == -1

(C++Builder & GNU-C++)

-16 == 1111 0000 -16 >> 2 == 1111 1100 == -4

(C++Builder & GNU-C++)

PROCEDIMIENTO DE EJEMPLOvoid desplazamientoADerecha(void){

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

* Este procedimiento hace uso de el operador de desplazamiento *

* hacia la derecha >> *

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

int x = 128;

cout << "\nEl tamanio de una variable int es: " << sizeof(int) << endl;

cout << "\nEl valor inicial de x: " << x << endl;

for (unsigned i = 1; i <= 8; i++)

{

unsigned desplazado = x >> i;

cout << "\nEl numero: " << desplazado << endl;

}

cout << "\nEl valor final de x: " << x << endl;

}

top related