Nesta aula vamos aprender como funciona o operador AND ( & ) bit a bit, na linguagem de programação C. Com esta operação é possível testar se um determinado bit está ligado ou desligado ou ainda descobrir se um número é par ou ímpar.
Operador bit a bit AND ( & )
A operação bit a bit & é muito semelhante à operação && que já conhecemos, inclusive possui a mesma tabela verdade.
A | B | A & B |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
A operação é realizada sobre cada bit. Assim, no resultado final cada bit será 1 apenas se ambos os bits da operação forem 1. Vamos a um exemplo para facilitar a compreensão. Sejam as seguintes variáveis:
/* Operação AND bit a bit em C */ int a, b; a = 30; // 0000.0000.0001.1110 em binário b = 19; // 0000.0000.0001.0011 c = a & b; // 0000.0000.0001.0010 = 18
A variável c possuirá o valor 18 em decimal. A princípio esse valor pode não fazer sentido, mas observe que é exatamente o resultado da operação & bit a bit entre as variáveis a e b.
Programa de teste:
/* Testando o operador AND bit a bit em C */ int main( ){ int a, b, c; a = 30; b = 19; c = a & b; printf("%d & %d = %d\n", a, b, c); return 0; }
Perceba que o resultado é completamente diferente do operador &&. Ao fazer esta operação:
a = 30; // 0000.0000.0001.1110
b = 19; // 0000.0000.0001.0011
c = a && b; // 0000.0000.0000.0001 = 1
O resultado será 1 pois o operador && não faz a operação bit a bit, mas verifica qual valor é diferente de nulo ou diferente de falso. Como na linguagem C zero é falso e tudo que for diferente de zero é verdadeiro, o resultado será 1, pois as variáveis ‘a’ e ‘b’ são verdadeiras (diferente de zero).
Caso o valor de uma das variáveis seja alterado para zero, assim:
a = 0; // 0000.0000.0000.0000
b = 19; // 0000.0000.0001.0011
c = a && b; // 0000.0000.0000.0000 = 0
Então o resultado será zero, pois uma das variáveis, a variável ‘a’, não é verdadeira.
Aplicações:
1) Testar se um bit é 0 ou 1
A operação AND bit a bit pode ser utilizada para testar se um determinado bit é zero ou um. Vamos a um exemplo. Imagine que precisamos saber se o quarto bit (da direita para esquerda) de uma variável que possui o valor 73 é zero ou um. Para fazer isso basta criar uma máscara onde apenas o bit a ser testado é 1 e realizar a operação AND, como feito a seguir:
01001001 (73 em binário)
& 00001000 ( 1 << 3 ), máscara para testar o bit-3 (quarto bit da direita para a esquerda)
—————
00001000
Como apenas o quarto bit é 1 em ambos os valores, apenas este bit será 1 no resultado, confirmando que o bit testado está ligado, ou seja, é 1. Se o bit testado fosse 0, o resultado final seria 0, confirmando que o bit testado está desligado.
Programa de teste:
/* Programa para testar o quarto bit da variável a */ int main(){ int a, b; a = 73; // 01001001 (73 em binário) b = a & (1 << 3); // 00001000 ( 1 << 3 ), para testar o bit-3 (quarto bit) printf("a: %d\tb: %d\n", a, b); b = a & (1 << 4); // 00010000 ( 1 << 4 ), para testar o bit-4 (quinto bit) printf("a: %d\tb: %d\n", a, b); return 0; }
2) Verificando se um número é par ou ímpar.
Todo número par, quando escrito em binário, terá o bit menos significativo (à direita) igual a zero. Assim, basta testar o bit menos significativo de qualquer valor inteiro para saber se o mesmo é par ou ímpar.
01110100 (116 em binário)
& 00000001 (1 em binário)
————-
00000000 → é par
Agora com um número ímpar:
01100001 (97 em binário)
& 00000001 (1 em binário)
————-
00000001
Programa de teste:
/* Testando se um número é par ou ímpar com a operação bit a bit AND ( & ) */ int main(){ int n = 97; if( n & 1 ) printf("Numero impar.\n") ; else printf("Numero par.\n") ; return 0; }
3) Limpar um bit (colocar um bit em zero)
Este operador pode ser utilizado em conjunto com os operadores de deslocamento e de negação para limpar um bit, ou seja, setar um bit com o valor zero.
Imagine um bit qualquer representado assim: xxxx.xxxx
Como limpar o bit 4? Observe que o bit 4 é o quinto bit da direita para a esquerda. O bit 0 é o bit mais à direita e o bit 7 é o bit mais à esquerda.
Limpar o bit 4 significa atingir o seguinte resultado: xxx0.xxxx
Esse resultado pode ser obtido por meio da operação & com esta sequência de bits 1110.1111. Esta sequência de bits é chamada de máscara, pois ela é utilizada para se atingir um determinado objetivo.
A pergunta agora é: como gerar a máscara 1110.1111?
É simples. Podemos partir do número 1 fazendo um deslocamento de 4 para a esquerda, assim: 1 << 4. O resultado será a máscara 0001.0000. Porém esta máscara é o contrário da máscara que precisamos, certo? Justamente por ser o contrário, basta negá-la e teremos a máscara 1110.1111.
Agora, basta fazer a operação & entre os dois valores, assim:
xxxx.xxxx
& 1110.1111
Como a máscara possui 1 em todas as posições exceto na que desejamos limpar e estamos realizando a operação &, será mantido o valor original em todas as posições, exceto a que desejamos limpar, que será setada para zero. O resultado final será: xxx0.xxxx.
Programe de teste:
/* Setando um bit específico para zero */ int main(){ int a, b; a = 25; // 0001.1001 b = a & (~(1 << 4)); // 0000.1001 = 9 printf("a: %d\tb: %d\n", a, b); a = 50; // 0011.0010 b = a & (~(1 << 4)); // 0010.0010 = 34 printf("a: %d\tb: %d\n", a, b); return 0; }