Soy bastante nuevo en la programación en C y encontré un poco de enmascaramiento. ¿Alguien puede explicarme el concepto general y la función del enmascaramiento de bits? Los ejemplos son muy apreciados.
Soy bastante nuevo en la programación en C y encontré un poco de enmascaramiento. ¿Alguien puede explicarme el concepto general y la función del enmascaramiento de bits? Los ejemplos son muy apreciados.
Respuestas:
Una máscara define qué bits desea conservar y qué bits desea eliminar.
El enmascaramiento es el acto de aplicar una máscara a un valor. Esto se logra haciendo:
A continuación se muestra un ejemplo de extracción de un subconjunto de los bits en el valor:
Mask: 00001111b
Value: 01010101b
Aplicar la máscara al valor significa que queremos borrar los primeros 4 bits (superiores) y mantener los últimos 4 bits (inferiores). Por lo tanto, hemos extraído los 4 bits inferiores. El resultado es:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
El enmascaramiento se implementa usando AND, por lo que en C obtenemos:
uint8_t stuff(...) {
uint8_t mask = 0x0f; // 00001111b
uint8_t value = 0x55; // 01010101b
return mask & value;
}
Aquí hay un caso de uso bastante común: extraer bytes individuales de una palabra más grande. Definimos los bits de orden superior en la palabra como el primer byte. Utilizamos dos operadores para esto &
, y >>
(desplazamiento a la derecha). Así es como podemos extraer los cuatro bytes de un entero de 32 bits:
void more_stuff(uint32_t value) { // Example value: 0x01020304
uint32_t byte1 = (value >> 24); // 0x01020304 >> 24 is 0x01 so
// no masking is necessary
uint32_t byte2 = (value >> 16) & 0xff; // 0x01020304 >> 16 is 0x0102 so
// we must mask to get 0x02
uint32_t byte3 = (value >> 8) & 0xff; // 0x01020304 >> 8 is 0x010203 so
// we must mask to get 0x03
uint32_t byte4 = value & 0xff; // here we only mask, no shifting
// is necessary
...
}
Tenga en cuenta que puede cambiar el orden de los operadores anteriores, primero puede hacer la máscara, luego el cambio. Los resultados son los mismos, pero ahora tendría que usar una máscara diferente:
uint32_t byte3 = (value & 0xff00) >> 8;
&
.
#define MASK 0x000000FF .... my_uint32_t &= ~MASK
.
b
para indicar el literal binario no es compatible con todos los compiladores, ¿correcto?
Enmascarar significa mantener / cambiar / eliminar una parte deseada de la información. Veamos una operación de enmascaramiento de imágenes; como esta operación de enmascaramiento está eliminando cualquier cosa que no sea piel
Estamos haciendo Y operación en este ejemplo. También hay otros operadores de enmascaramiento: OR , XOR .
Bit-Masking significa imponer una máscara sobre bits. Aquí hay un enmascaramiento de bits con AND -
1 1 1 0 1 1 0 1 [input] (&) 0 0 1 1 1 1 0 0 [mask] ------------------------------ 0 0 1 0 1 1 0 0 [output]
Por lo tanto, solo quedan los 4 bits centrales (ya que estos bits están 1
en esta máscara).
Veamos esto con XOR -
1 1 1 0 1 1 0 1 [input] (^) 0 0 1 1 1 1 0 0 [mask] ------------------------------ 1 1 0 1 0 0 0 1 [output]
Ahora, los 4 bits centrales se voltean (se 1
convirtieron 0
, se 0
convirtieron 1
).
Entonces, usando bit-mask podemos acceder a bits individuales [ ejemplos ]. A veces, esta técnica también se puede utilizar para mejorar el rendimiento. Toma esto por ejemplo
bool isOdd(int i) {
return i%2;
}
Esta función indica si un número entero es impar / par. Podemos lograr el mismo resultado con más eficiencia usando bit-mask-
bool isOdd(int i) {
return i&1;
}
Explicación breve : si el bit menos significativo de un número binario es 1
entonces es impar; porque 0
será parejo. Entonces, al hacer AND con 1
, estamos eliminando todos los demás bits, excepto el bit menos significativo, es decir:
55 -> 0 0 1 1 0 1 1 1 [input] (&) 1 -> 0 0 0 0 0 0 0 1 [mask] --------------------------------------- 1 <- 0 0 0 0 0 0 0 1 [output]