Eu sou bastante novo na programação C e encontrei um pouco de mascaramento. Alguém pode me explicar o conceito geral e a função do mascaramento de bits? Exemplos são muito apreciados.
Eu sou bastante novo na programação C e encontrei um pouco de mascaramento. Alguém pode me explicar o conceito geral e a função do mascaramento de bits? Exemplos são muito apreciados.
Respostas:
Uma máscara define quais bits você deseja manter e quais bits você deseja limpar.
Mascarar é o ato de aplicar uma máscara a um valor. Isso é realizado fazendo:
Abaixo está um exemplo de extração de um subconjunto dos bits no valor:
Mask: 00001111b
Value: 01010101b
A aplicação da máscara ao valor significa que queremos limpar os primeiros 4 bits (superiores) e manter os últimos 4 bits (inferiores). Assim, extraímos os 4 bits inferiores. O resultado é:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
O mascaramento é implementado usando AND, portanto, em C, obtemos:
uint8_t stuff(...) {
uint8_t mask = 0x0f; // 00001111b
uint8_t value = 0x55; // 01010101b
return mask & value;
}
Aqui está um caso de uso bastante comum: Extraindo bytes individuais de uma palavra maior. Definimos os bits de alta ordem na palavra como o primeiro byte. Usamos dois operadores para isso &
, e >>
(shift right). É assim que podemos extrair os quatro bytes de um número inteiro 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
...
}
Observe que você pode mudar a ordem dos operadores acima, primeiro pode fazer a máscara e depois o turno. Os resultados são os mesmos, mas agora você teria que usar uma máscara diferente:
uint32_t byte3 = (value & 0xff00) >> 8;
&
.
#define MASK 0x000000FF .... my_uint32_t &= ~MASK
.
b
literal binário para indicar não é suportado por todos os compiladores, correto?
Mascarar significa manter / alterar / remover uma parte desejada da informação. Vamos ver uma operação de mascaramento de imagens; como esta operação de mascaramento está removendo qualquer coisa que não seja de pele
Estamos fazendo E operação neste exemplo. Existem também outros operadores de mascaramento - OU , XOR .
Mascaramento de bits significa impor máscara sobre bits. Aqui está um pouco de mascaramento com 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]
Portanto, apenas os 4 bits do meio (como esses bits estão 1
nessa máscara) permanecem.
Vamos ver isso com o 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]
Agora, os 4 bits do meio são invertidos ( 1
tornaram-se 0
, 0
tornaram-se 1
).
Assim, usando máscara de bits, podemos acessar bits individuais [ exemplos ]. Às vezes, essa técnica também pode ser usada para melhorar o desempenho. Veja isso por exemplo:
bool isOdd(int i) {
return i%2;
}
Esta função informa se um número inteiro é ímpar / par. Podemos alcançar o mesmo resultado com mais eficiência usando máscara de bits
bool isOdd(int i) {
return i&1;
}
Breve explicação : se o bit menos significativo de um número binário for 1
, ele será ímpar; por 0
isso vai ser mesmo. Então, fazendo AND com 1
estamos removendo todos os outros bits, exceto o bit menos significativo, ou seja:
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]