Introducción: El Poder a Nivel de Bit¶
En el corazón de cada operación que realiza una computadora se encuentran los bits. La manipulación de bits es el conjunto de técnicas que nos permite interactuar directamente con esta representación binaria de los datos. En C, dominar estas técnicas es una habilidad práctica y poderosa para optimizar el rendimiento, ahorrar memoria e interactuar con hardware.
Representación Binaria¶
Todos los tipos de datos en C se almacenan como una secuencia de bits. Un
unsigned char
(1 byte) que representa el número 200, en binario es 11001000
.
Bit: 7 6 5 4 3 2 1 0
Valor: 128 64 32 16 8 4 2 1
-----------------------------------------
Binario: 1 1 0 0 1 0 0 0
Suma: 128 + 64+ 0 + 0 + 8 + 0 + 0 + 0 = 200
Los Operadores a Nivel de Bits¶
1. AND a nivel de bits (&
)¶
El bit del resultado es 1
solo si ambos bits correspondientes en los operandos
son 1
. Su uso principal es para verificar o apagar bits.
Solution to Exercise 1
#include <stdbool.h>
bool es_par(int numero) {
// La máscara 1 (00000001) aísla el último bit.
// Si el resultado de (numero & 1) es 0, el bit era 0.
return (numero & 1) == 0;
}
2. OR a nivel de bits (|
)¶
El bit del resultado es 1
si al menos uno de los bits correspondientes es 1
.
Su uso principal es para encender bits.
3. XOR a nivel de bits (^
)¶
El bit del resultado es 1
solo si los bits correspondientes son
diferentes. Su uso principal es para alternar (toggle) bits.
4. NOT a nivel de bits (~
)¶
El operador NOT (complemento a uno) invierte todos los bits de su operando. 0
se convierte en 1
y 1
en 0
.
Crear una Máscara para Apagar Escribí una expresión que cree una
máscara para apagar el 2do bit (posición 1) de un char
, sin afectar a los
demás.
:::{solution} mask
:class: dropdown
```{code-block} c
// Máscara para el 2do bit: (1 << 1) -> 00000010
// Máscara invertida: ~(1 << 1) -> 11111101
unsigned char mascara_apagado = ~(1 << 1);
```
5. Desplazamientos (<<
y >>
)¶
<<
: Desplaza los bits a la izquierda. Equivale a multiplicar por potencias de 2.Ejemplo:
5 << 2
00000101 (5) << 2 --> 00010100 (20)
>>
: Desplaza los bits a la derecha. Equivale a dividir por potencias de 2.Ejemplo:
20 >> 2
00010100 (20) >> 2 --> 00000101 (5)
Ejercicios de Aplicación (Recetario)¶
1. Obtener el N-ésimo Bit¶
2. Establecer el N-ésimo Bit¶
3. Limpiar el N-ésimo Bit¶
4. Contar Bits Encendidos (Hamming Weight)¶
Solution to Exercise 9
Algoritmo de Brian Kernighan: La operación
n & (n - 1)
apaga el bit encendido menos significativo. El número de veces que
se puede hacer esta operación antes de que n
sea 0 es el número de bits
encendidos.
int contar_bits_encendidos(int n) {
int contador = 0;
while (n > 0) {
n = n & (n - 1); // Apaga el bit '1' de más a la derecha
contador++;
}
return contador;
}
5. Verificar si es Potencia de Dos¶
Glosario¶
- Máscara de Bits (Bitmask)
- Un valor numérico utilizado para seleccionar, modificar o consultar bits específicos de otro valor mediante operaciones a nivel de bits como AND, OR y XOR.
- Endianness
- Se refiere al orden en que se almacenan en memoria los bytes que componen un tipo de dato multibyte. Es una consideración crucial para la portabilidad de datos binarios.