Operadores de bits

Todos los operadores de bits trabajan con enteros BIGINT, es decir con 64 bits.

Los operadores son los habituales: o, y, o exclusivo, complemento y rotaciones a derecha e izquierda.

Operador de bits O

El símbolo empleado es |. Este operador es equivalente al operador OR que vimos para álgebra de Boole, pero se aplica bit a bit entre valores enteros de 64 bits.

Las tablas de verdad para estos operadores son más simples, ya que los bits no pueden tomar valores nulos:

Bit A Bit B A | B
0 0 0
0 1 1
1 0 1
1 1 1

Las operaciones con operadores de bits se realizan tomando los bits de cada operador uno a uno. Ejemplo:

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
O 00101101 11011110 100010100 11101011 11010010 11010101 00101001 11010010
  11101111 11011110 110111110 11101011 11011111 11111111 11111111 11010111

Por ejemplo:

mysql> SELECT 234 | 334, 32 | 23, 15 | 0;
+-----------+---------+--------+
| 234 | 334 | 32 | 23 | 15 | 0 |
+-----------+---------+--------+
|       494 |      55 |     15 |
+-----------+---------+--------+
1 row in set (0.00 sec)

mysql>

Operador de bits Y

El símbolo empleado es &. Este operador es equivalente al operador AND que vimos para álgebra de Boole, pero aplicado bit a bit entre valores enteros de 64 bits.

La tabla de verdad para este operador es:

Bit A Bit B A & B
0 0 0
0 1 0
1 0 0
1 1 1

Al igual que con el operador |, con el operador & las operaciones se realizan tomando los bits de cada operador uno a uno. Ejemplo:

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
Y 00101101 11011110 100010100 11101011 11010010 11010101 00101001 11010010
  00100001 11001000 000000000 11100011 00000010 10000000 00101001 00000000

Por ejemplo:

mysql> SELECT 234 & 334, 32 & 23, 15 & 0;
+-----------+---------+--------+
| 234 & 334 | 32 & 23 | 15 & 0 |
+-----------+---------+--------+
|        74 |       0 |      0 |
+-----------+---------+--------+
1 row in set (0.00 sec)

mysql>

Operador de bits O exclusivo

El símbolo empleado es ^. Este operador es equivalente al operador XOR que vimos para álgebra de Boole, pero aplicado bit a bit entre valores enteros de 64 bits.

La tabla de verdad para este operador es:

Bit A Bit B A ^ B
0 0 0
0 1 1
1 0 1
1 1 0

Al igual que con los operadores anteriores, con el operador ^ las operaciones se realizan tomando los bits de cada operador uno a uno. Ejemplo:

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
^ 00101101 11011110 100010100 11101011 11010010 11010101 00101001 11010010
  11001110 00010100 110111110 00001000 11011101 01111111 11010110 11010111

Por ejemplo:

mysql> SELECT 234 ^ 334, 32 ^ 23, 15 ^ 0;
+-----------+---------+--------+
| 234 ^ 334 | 32 ^ 23 | 15 ^ 0 |
+-----------+---------+--------+
|       420 |      55 |     15 |
+-----------+---------+--------+
1 row in set (0.00 sec)

mysql>

Operador de bits de complemento

El símbolo empleado es ~. Este operador es equivalente al operador NOT que vimos para álgebra de Boole, pero aplicado bit a bit entre valores enteros de 64 bits.

Se trata de un operador unitario, y la tabla de verdad es:

Bit A ~A
0 1
1 0

Al igual que con los operadores anteriores, con el operador ~ las operaciones se realizan tomando los bits del operador uno a uno. Ejemplo:

~ 11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
  00011100 00110101 101010101 00011100 11110000 01010101 00000000 11111010

Por ejemplo:

mysql> SELECT ~234, ~32, ~15;
+----------------------+----------------------+----------------------+
| ~234                 | ~32                  | ~15                  |
+----------------------+----------------------+----------------------+
| 18446744073709551381 | 18446744073709551583 | 18446744073709551600 |
+----------------------+----------------------+----------------------+
1 row in set (0.00 sec)

mysql>

Como vemos en el ejemplo, el resultado de aplicar el operador de complemento no es un número negativo. Esto es porque si no se especifica lo contrario, se usan valores BIGINT sin signo.

Si se fuerza un tipo, el resultado sí será un número de signo contrario. Por ejemplo:

mysql> SET @x = ~1;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x;
+------+
| @x   |
+------+
| -2   |
+------+
1 row in set (0.00 sec)

mysql>

Para los que no estén familiarizados con el álgebra binaria, diremos que para consegir el negativo de un número no basta con calcular su complemento. Además hay que sumar al resultado una unidad:

mysql> SET @x = ~1 +1, @y = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x + @y;
+---------+
| @x + @y |
+---------+
|       0 |
+---------+
1 row in set (0.00 sec)

mysql>

Operador de desplazamiento a la izquierda

El símbolo empleado es <<. Se trata de un operador binario. El resultado es que los bits del primer operando se desplazan a la izquieda tantos bits como indique el segundo operando. Por la derecha se introducen otros tantos bits con valor 0. Los bits de la parte izquierda que no caben en los 64 bits, se pierden.

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
<< 12
  10100101 010101110 00110000 11111010 10101111 11110000 01010000 00000000

El resultado, siempre que no se pierdan bits por la izquierda, equivale a multiplicar el primer operando por dos para cada desplazamiento.

Por ejemplo:

mysql> SELECT 234 << 25, 32 << 5, 15 << 1;
+------------+---------+---------+
| 234 << 25  | 32 << 5 | 15 << 1 |
+------------+---------+---------+
| 7851737088 |    1024 |      30 |
+------------+---------+---------+
1 row in set (0.00 sec)

mysql>

Operador de desplazamiento a la derecha

El símbolo empleado es >>. Se trata de un operador binario. El resultado es que los bits del primer operando se desplazan a la derecha tantos bits como indique el segundo operando. Por la izquieda se introducen otros tantos bits con valor 0. Los bits de la parte derecha que no caben en los 64 bits, se pierden.

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
>> 7
  00000001 11000111 10010100 101010101 11000110 00011111 01010101 11111110

El resultado equivale a dividir el primer operando por dos para cada desplazamiento.

Por ejemplo:

mysql> SELECT 234 >> 25, 32 >> 5, 15 >> 1;
+-----------+---------+---------+
| 234 >> 25 | 32 >> 5 | 15 >> 1 |
+-----------+---------+---------+
|         0 |       1 |       7 |
+-----------+---------+---------+
1 row in set (0.00 sec)

mysql>

Contar bits

El último operador de bits del que dispone MySQL es BIT_COUNT(). Este operador devuelve el número de bits iguales a 1 que contiene el argumento especificado. Por ejemplo:

mysql> SELECT BIT_COUNT(15), BIT_COUNT(12);
+---------------+---------------+
| BIT_COUNT(15) | BIT_COUNT(12) |
+---------------+---------------+
|             4 |             2 |
+---------------+---------------+
1 row in set (0.00 sec)

mysql>