1.5 Manejo de Bits

Como sabrán, los datos en una computadora internamente se representan en código binario. El microprocesador solo entiende de ceros y unos. Luego mediante una serie de procesos nosotros vemos a este código ya transformado en números, caracteres , imágenes y sonido. Pero en realidad en la trastienda todo sigue siendo binario.

Los Bits

El método mas sencillo de representación son los números naturales. Por ejemplo, si tengo el número 85 en decimal, solo tengo que llevarlo a binario y obtengo una serie de unos y ceros. :

1010101 = 85 en binario

Cada dígito (un cero o un uno) de este número se llama bit. Java tiene una serie de operadores capaces de manipular estos dígitos, son los operadores de bits.


Operador Utilización Resultado
<< A <<> Desplazamiento de A a la izquierda en
B posiciones
>> A >> B Desplazamiento de A a la derecha en
B posiciones, tiene en cuenta el signo.
>>> A >>> B Desplazamiento de A a la derecha en
B posiciones, no tiene en cuenta el signo.
& A & B Operación AND a nivel de bits
| A | B Operación OR a nivel de bits
^ A ^ B Operación XOR a nivel de bits
~ ~A Complemento de A a nivel de bits


Para operar a nivel de bit es necesario tomar toda la longitud predefinida para el tipo de dato. Estamos acostumbrados a desechar los ceros a la izquierda en nuestra representación de números. Pero aquí es importante. Si trabajamos una variable de tipo short con un valor de 3, está representada de la siguiente manera :

0000000000000011

Aquí los 16 bits de un short se tienen en cuenta.

Desplazamientos

Los operadores de desplazamiento, mueven los bits a la izquierda o a la derecha. El primer operando será la victima a sacudir. El segundo indicará cuantas posiciones.

Desplazamiento a la izquierda con signo (cíclico)

Deseamos correr el número 33 dos posiciones a la izquierda. Entonces realizamos :

int j = 33;
int k = j <<>

Como resultado obtenemos el número original.

00000000000000000000000010000100 : k = 132 00000000000000000000000000100001 : m = 132 >> 2 ; m = 33

Podemos ver que el corrimiento a la derecha realiza una división de enteros. Divide por 2, tantas veces como posiciones desplazadas. Los huecos que quedan por la izquierda se cubren con los bits que van saliendo por la derecha (es cíclico).

Veamos que ocurre si pretendemos realizar un desplazamiento a la derecha con un número negativo. Tengan en cuenta que la representación de números es de complemento a 2. Si tengo una variable de tipo int con el valor –1 , internamente está almacenada de la siguiente forma :

11111111111111111111111111111111 : -1 complemento a 2

Ahora realicemos un programa para ver que ocurre con el desplazamiento.

public class CorreNeg {
public static void main(String args[]){
int x = -1;
int y = x >> 2;
System.out.println("El resultado es: " + String.valueOf(y));
}
}

La salida del programa nos indica que:

El resultado es: -1

Quedó exactamente igual. Prueben de correr el número tantas posiciones como tengan ganas y obtendrán el mismo resultado. Esto ocurre porque en el desplazamiento, los "huecos" que quedan a la izquierda se rellenan con el bit uno (1), quedando inalterable.

Este operador desplaza el conjunto de bit a la derecha y agrega a la izquierda los bits que faltan según el signo. Si se encuentra con un número positivo, agrega ceros, en cambio si son negativos agrega unos. Se lo conoce como desplazamiento con signo.

Desplazamiento a la derecha sin signo

Modifiquemos ligeramente el programa anterior agregándole al operador un símbolo >. Nos queda de esta manera :

int x = -1;
int y = x >>> 2;

Si ejecutamos el programa nos dice lo siguiente :

El resultado es: 1073741823

Veamos de donde salió este número raro. Si lo llevamos a binario tenemos :

00111111111111111111111111111111 : 1073741823 en binario

Ahora nos damos cuenta que se han agregado dos ceros a la izquierda. Este operador desplaza a la derecha, pero no tiene en cuenta el signo. Siempre agrega bit con el valor cero, por lo que se llama desplazamiento sin signo.

Operadores lógicos de bits

Estos operadores extienden las operaciones booleanas a los enteros. Para comprender como trabajan debemos descomponer los enteros en un conjunto de bits. El operador aplicará una operación lógica bit por bit, tomando el valor de uno como verdadero y el valor de cero como falso. De un operando toma un bit y aplica la operación al bit que tiene la misma posición del segundo operando. Como resultado obtenemos otro entero.

Operador AND de Bits

Si ambos bits comparados son 1, establece el resultado en 1. De lo contrario da como resultado 0.

int k = 132; // k: 00000000000000000000000010000100
int l = 144; // l: 00000000000000000000000010010000
int m = k & l; // m: 00000000000000000000000010000000

El resultado da 128

Operador XOR de Bits

Si uno de los bits comparados es 0 y el otro 1, el resultado es 1. Si ambos bits comparados son iguales, el resultado es 0.

int k = 132; // k: 00000000000000000000000010000100
int l = 144; // l: 00000000000000000000000010010000
int m = k ^ l; // m: 00000000000000000000000000010100

El resultado da 20

Operador NOT de Bits

Sólo invierte los bits, es decir, convierte los ceros en unos y viceversa. Observemos que es el único de esta familia que tiene un solo operando.

int k = 132; // k: 00000000000000000000000010000100
int m = ~k; // m: 11111111111111111111111101111011

El resultado da -133

Como los enteros negativos en Java se representan con el método del complemento a dos, podemos realizar un sencillo experimento de cambiarle el signo a un número. Para realizarlo debemos aplicar a un entero el operador NOT y sumarle uno.

int x = 123;
int y = ~x;
int z = y + 1;

El resultado da -123,


Fuente Original:

http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Java_/_Operadores_de_bits

No hay comentarios:

Publicar un comentario