# Programación en Java/Operadores 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 más 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:
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.
Operadores de bits :
| Operador | Utilización | Resultado |
| << | A << B | 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 :
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

Deseamos correr el número 33 dos posiciones a la izquierda. Entonces realizamos :
Este es el resultado:
Cada "hueco" que queda a la derecha tras correr este número se rellena con ceros. Los bits a la izquierda se pierden, no es una operación de rotación. Si prestamos atención, observaremos que esta operación multiplicó a j por 2 tantas veces como posiciones se ha desplazado. En este caso se multiplicó por 4 ( 2 x 2 ). Hay que notar que el signo del número puede cambiar tras la operación (por ejemplo 1 << 31 = -2147483648).

### Desplazamiento a la derecha con signo

Volvamos a colocar como estaban los bits del caso anterior. Queremos obtener nuevamente el número 33. Para esto desplazamos el número 132 dos posiciones a la derecha.
Como resultado obtenemos el número original.
Podemos ver que el corrimiento a la derecha realiza una división de enteros. Divide por 2, tantas veces como posiciones desplazadas.
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 :
Ahora realicemos un programa para ver que ocurre con el desplazamiento.
La salida del programa nos indica que:
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 bit de signo, o sea el más significativo. Si se encuentra con un número positivo, el bit de signo vale 0, entonces agrega ceros, en cambio si son negativos el bit de signo vale 1, entonces agrega unos. Este proceso, denominado extensión de signo mantiene el signo del número como si se tratara de una división. Por esto 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 :
Si ejecutamos el programa nos dice lo siguiente :
Veamos de donde salió este número raro. Si lo llevamos a binario tenemos :
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. Este operador suele ser más adecuado que el >> cuando queremos manipular los bits mismos, no su representación numérica.

## 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.

### Operador OR de Bits

Si por lo menos uno de los dos bits comparados es 1, establece el resultado en 1. De lo contrario da como resultado 0.

### 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.

### 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.
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.

## Para saber más

* Bit
* Lógica binaria