1. Desplazamiento a la izquierda bit a bit

Java también tiene 3 operadores de desplazamiento bit a bit : si realmente lo necesita, puede simplemente desplazar todos los bits de un número varias posiciones hacia la izquierda o hacia la derecha.

Para desplazar los bits de un número a la izquierda, necesita el operador de desplazamiento a la izquierda bit a bit . Así se escribe:

a << b

Where aes el número cuyos bits se están desplazando, y bes un número que indica cuántas veces se desplazan los bits del número ahacia la izquierda. Durante esta operación, los bits de orden inferior agregados a la derecha son ceros.

Ejemplos:

Ejemplo Resultado
0b00000011 << 1
0b00000110
0b00000011 << 2
0b00001100
0b00000011 << 5
0b01100000
0b00000011 << 20
0b001100000000000000000000

Desplazar un dígito a la izquierda tiene el mismo efecto que multiplicar un número por 2.

¿Quieres multiplicar un número por 16? 16 es lo mismo que 2 4 . Así que desplazas el número 4 dígitos a la izquierda


2. Desplazamiento bit a bit a la derecha

Los bits también se pueden desplazar hacia la derecha. Para ello, utilice el operador de desplazamiento a la derecha bit a bit . Así se escribe:

a >> b

Donde aes el número cuyos bits se desplazan y bes el número de veces que se desplazan los bits del número aa la derecha.

Ejemplos:

Ejemplo Resultado
0b11000011 >> 1
0b01100001
0b11000011 >> 2
0b00110000
0b11000011 >> 5
0b00000110
0b11000011 >> 20
0b00000000

Desplazar un dígito a la derecha tiene el mismo efecto que dividir un número por 2.

Durante esta operación, los bits de orden superior agregados a la izquierda son ceros, ¡ pero no siempre !

¡Importante!

El bit más a la izquierda de un número con signo se llama bit de signo : si el número es positivo, lo es 0; pero si el número es negativo, este bit es 1.

Al desplazar los bits de un número hacia la derecha, el valor del bit de signo normalmente también se desplazaría y el signo del número se perdería. En consecuencia, para números negativos (donde el bit más a la izquierda es 1), este bit recibe un tratamiento especial. Al desplazar los bits de un número a la derecha, se 0agrega a a la izquierda si el bit más a la izquierda era 0, y 1se agrega a a la izquierda si el bit más a la izquierda era 1.

Pero en el ejemplo anterior, ese no parece ser el resultado. ¿Por qué? Porque los literales enteros son ints, y  en realidad significan . Es decir, el bit más a la izquierda es cero.0b111111110b00000000000000000000000011111111

Muchos programadores se sienten frustrados por este comportamiento de desplazamiento a la derecha y preferirían que el número siempre se rellenara con ceros. Así que Java agregó otro operador de desplazamiento a la derecha .

Así se escribe:

a >>> b

Donde a es el número cuyos bits se desplazan y b  es el número de veces que se desplazan los bits del número aa la derecha. Este operador siempre añade ceros a la izquierda, independientemente del valor original del bit de signo del número a.



3. Trabajar con banderas

Los programadores crearon un campo de estudio casi completamente nuevo sobre la base de operaciones bit a bit y de cambio: trabajar con banderas.

Cuando las computadoras tenían muy poca memoria, era muy popular incluir mucha información en un solo número. Un número se trató como una matriz de bits: un int tiene 32 bits y un long tiene 64 bits.

Puede escribir mucha información en dicho número, especialmente si necesita almacenar valores lógicos ( trueo ). falseUn solo longes como una booleanmatriz compuesta por 64 elementos. Estos bits se denominaron banderas y se manipularon mediante las siguientes operaciones:

  • establecer bandera
    (hacer un bit específico igual a 1)
  • restablecer bandera
    (hacer un bit específico igual a 0)
  • marcar la bandera
    (verifique el valor de un bit específico)

Y así es como se hace con operadores bit a bit.

Poniendo una bandera

Para establecer un bit específico en 1, debe realizar una operación OR bit a bit entre el número cuyo bit desea establecer y un número creado especialmente, donde solo ese bit es 1.

Por ejemplo, suponga que tiene el número 0b00001010y necesita establecer el quinto bit en 1. En ese caso, es necesario:

0b00001010 | 0b00010000 = 0b00011010

Si el quinto bit ya se hubiera establecido en uno, entonces nada habría cambiado.

En general, la operación de establecer una bandera se puede escribir de la siguiente manera

a | (1 << b)

¿Dónde a está el número cuyo bit se establecerá en 1. Y b es la posición del bit a establecer. Usar el operador de desplazamiento a la izquierda es muy conveniente aquí, ya que puede saber de inmediato con qué bit estamos trabajando.

Restablecimiento de una bandera

Para restablecer un bit específico (es decir, establecerlo en 0) sin alterar otros bits, debe realizar una &operación entre el número cuyo bit desea restablecer (es decir, establecer en 0) y un número creado especialmente, donde todos los bits son iguales 1excepto para el bit que desea restablecer.

Por ejemplo, suponga que tiene el número 0b00001010y necesita establecer el cuarto bit en 0. En ese caso, es necesario:

0b00001010 & 0b11110111 = 0b00000010

Si el cuarto bit ya se hubiera puesto a cero, nada habría cambiado.

En general, la operación de restablecer una bandera se puede escribir de la siguiente manera

a & ~(1 << b)

¿Dónde a está el número cuyo bit se restablecerá a 0. Y b es la posición del bit a borrar.

Para obtener un número donde todos los bits estén 1excepto el que queremos que sea cero, primero desplazamos 1 b  posiciones a la izquierda y luego usamos el NOToperador bit a bit para invertir el resultado.

Comprobación de una bandera

Además de establecer o restablecer un indicador específico, a veces solo necesita verificar si un indicador determinado está establecido, es decir, si un determinado bit es igual a 1. Esto es bastante fácil de hacer con un bit a bit &.

Por ejemplo, suponga que necesita verificar si el cuarto bit está configurado 1en el número 0b00001010. Entonces necesitas hacer esto:

if ( (0b00001010 & 0b00001000) == 0b00001000 )

En general, la operación de verificar una bandera se puede escribir de la siguiente manera

(a & (1 << b)) == (1 << b)

¿Dónde a está el número cuyo bit se está comprobando? Y b es la posición del bit a comprobar.


4. Cifrado

XORLos programadores suelen utilizar la operación bit a bit para el cifrado simple. En general, dicho cifrado se ve así:

result = number ^ password;

¿ Dónde number están los datos que queremos encriptar? password Es un número especial que se usa como "contraseña" para los datos y result es el número encriptado.

number == (number ^ password) ^ password;

Lo importante aquí es que cuando el XORoperador se aplica dos veces a un número, produce el número original, independientemente de la "contraseña".

Para recuperarse number del encrypted result, solo necesita realizar la operación nuevamente:

original number = result ^ password;

Ejemplo:

class Solution
{
   public static int[] encrypt(int[] data, int password)
   {
     int[] result = new int[data.length];
     for (int i = 0; i <  data.length; i++)
       result[i] = data[i] ^ password;
     return result;
   }

   public static void main(String[] args)
   {
     int[] data =  {1, 3, 5, 7, 9, 11};
     int password = 199;

     // Encrypt the array of data
     int[] encrypted = encrypt(data, password);
     System.out.println(Arrays.toString(encrypted));

     // Decrypt the array of data
     int[] decrypted = encrypt(encrypted, password);
     System.out.println(Arrays.toString(decrypted));
   }
}