1. OPERADORES BIT A BIT
Profª Ms. Engª Elaine Cecília Gatto
Curso de Bacharelado em Engenharia de Computação
Universidade do Sagrado CoraçãO – USC
Bauru/SP
2. Operadores sobre bits
• Computadores representam internamente
todos os dados como sequencias de bits;
• Os bits podem assumir o valor 0 ou o valor 1;
• Na maioria dos sistemas, uma sequencia de 8
bits forma um byte – unidade de
armazenamento padrão para uma variável do
tipo char;
• Outros tipos de dados são armazenados em
números maiores de bytes;
• Os operadores sobre bits são usados para
manipular os bits de operandos inteiros;
• Os inteiros sem sinal normalmente são usados
com o os operadores sobre bits;
3. Operadores sobre bits
• Os operadores sobre bits são:
• Comparação dos dois operandos bit a bit:
– And (&)
– OR inclusivo ( | )
– OR exclusivo ( ^ )
• Deslocamento à esquerda ( < < )
• Deslocamenteo à direita ( > > )
• Complemento ( ~ )
• Ser capaz de operar no nível dos bits é
especialmente importante quando o programa
deve atuar diretamente no hardware da máquina.
4. Operadores sobre bits
AND
Os bits são definidos como 1 no resultado, se os bits
correspondentes em ambos os operandos forem 1.
OR inclusivo
Os bits são definidos como 1 no resultado, se pelo menos um dos
bits correspondentes em amobs os operandos for 1.
OR exclusivo
Os bits são definidos como 1 no resultado, se exatamente um dos
bits correspondentes em ambos os operandos for 1.
Deslocamento à
esquerda
Desloca os bits do primeiro operando à esquerda pelo número de
bits especificado pelo segundo operando: preenche a partir da
direita com zero (0) bits.
Deslocamento à
direita
Desloca os bits do primeiro operando à direita pelo número de bits
especificado pelo segundo operando: o método de preenchimento
a partir da esquerda depende da máquina.
Complemento de Todos os bits 0 são definidos como 1, e todos os bits 1 são
um
definidos como 0.
5. Exibição de um inteiro sem sinal
em bits
• Ao usar os operadores sobre bits, é útil
imprimir valores em sua representação binária
para ilustrar os efeitos exatos desses
operadores.
• O programa a seguir imprime um inteiro sem
sinal em sua representação binária em grupos
de 8 bits cada.
• Os inteiros sem sinal são armazenados, neste
exemplo, em 4 bytes ou 32 bits de memória.
6. Exibição de um inteiro sem sinal
em bits
#include <stdio.h>
void displayBits (unsigned value); //protótipo da
função
int main(void) {
unsigned x;
printf(“Digite um inteiro sem sinal: ”);
scanf(“%u”, &x);
displayBits(x); //chama a função
return 0;
}
//função: mostra bits de um valor inteiro
sem sinal
void displayBits(unsigned value) {
unsigned c; //contador
7. Exibição de um inteiro sem sinal
em bits
//declara displayMask e desloca 31 bits à
esquerda
unsigned displayMask = 1 << 31;
printf(“%10u = ”, value);
//percorre os bits
for( c=1; c<=32; c++) {
putchar(value & displayMask ? „1‟ : „0‟);
value <<= 1; //desloca valor à esquerda
em 1
if( c%8 == 0) { //gera espaço após 8
bits
putchar(„ ‟);
}
}
putchar(„ n ‟);
}
9. Exibição de um inteiro sem sinal
em bits
• A função displayBits usa o operador AND sobre
bits para combinar a variável VALUE com a
variável DISPLAYMASK.
• Frequentemente, o operador AND sobre bits é
usado como um operando chamado MÁSCARA –
um valor inteiro com bits específicos definidos
como 1.
• As máscaras são usadas para ocultar alguns bits
em um valor enquanto seleciona outros bits.
• Na função DISPLAYBITS, a variável máscara
DISPLAYMASK recebe o valor 1 << 31 (10000000
00000000 00000000 00000000)
10. Exibição de um inteiro sem sinal
em bits
• O operador de deslocamento à esquerda
desloca o valor 1 a partir do bit de baixa
ordem – mais à direita – para o bit de alta
ordem – mais à esquerda – em DISPLAYMASK,
e preenche bits 0 a partir da direita.
• A linha putchar(value & displayMask ? „1‟ : „0‟);
determina se 1 ou 0 deve ser impresso para o
bit mais à esquerda da variável VALUE.
• Quando
VALUE
e
DISPLAYMASK
são
combinados usando &, todos os bits, exceto o
bit de alta ordem na variável VALUE, são
mascarados – ocultados – pois qualquer bit
que passe por AND com 0 gera 0.
11. Exibição de um inteiro sem sinal
em bits
• O operador de deslocamento à esquerda
desloca o valor 1 a partir do bit de baixa
ordem – mais à direita – para o bit de alta
ordem – mais à esquerda – em DISPLAYMASK,
e preenche bits 0 a partir da direita.
• A linha putchar(value & displayMask ? „1‟ : „0‟);
determina se 1 ou 0 deve ser impresso para o
bit mais à esquerda da variável VALUE.
• Quando
VALUE
e
DISPLAYMASK
são
combinados usando &, todos os bits, exceto o
bit de alta ordem na variável VALUE, são
mascarados – ocultados – pois qualquer bit
que passe por AND com 0 gera 0.
12. Exibição de um inteiro sem sinal
em bits
• Se o bit mais à esquerda for 1, VALUE &
DISPLAYMASK será avaliado como um valor
diferente de zero – verdadeiro – e 1 será impresso
– caso contrário, 0 será impresso.
• A variável VALUE é, então, deslocada um bit à
esquerda pela expressão VALUE <<= 1 – isso
equivale a VALUE = VALUE << 1.
• Essas etapas são repetidas para cada bit na
variável UNSIGNED VALUE.
• Cuidado: usar o operador lógico AND (&&) para o
operador AND SOBRE BITS (&) e vice-versa
consiste em um erro.
15. Operador and: & e &=
• É um operador binário que executa um AND
com cada par de bits dos operandos.
• Cada bit do resultado é 1 somente quando os
dois bits operandos são 1; em qualquer
situação, o resultado é zero.
• O operador bit a bit AND é normalmente
usado para testar se um bit particular está
ligado ou desligado.
BIT 1 BIT
BIT &
• O processo de teste funciona,2 poisBIT2se
0
operarmos o bit a ser testado 0 com 01, o
1
0
resultado será verdadeiro somente se 0esse
0
1
0
bit estiver ligado.
1
1
1
16. Operador or: | e |=
• É um operador binário que executa um OR
com cada par de bits dos operandos.
• Cada bit do resultado é zero somente quando
os dois bits operandos são zero; em qualquer
outra situação, o resultado é um.
• O operador bit a bit OR é normalmente
usado para ligar um bit particular.
• O processo funciona, pois, se BIT 1 BIT 2 BIT 1 oBIT 2
operarmos | bit
a ser ligado com 1, o resultado 0
será
0
0
verdadeiro sempre.
1
0
1
0
1
1
1
1
1
17. Operador xor: ^ e ^=
• É um operador binário que executa um
XOR com cada par de bits dos operandos.
• Cada bit do resultado é 1 somente quando
os dois bits operandos são diferentes;
quando são iguais, o resultado é zero.
• O operador bit a bit XOR é normalmente
BIT 1 BIT 2 BIT 1 | BIT 2
usado para inverter o status0 de 0um bit.
0
1
0
1
0
1
1
1
1
0
18. Operador de complemento:
~ e ~=
• O operador de complemento opera um único
operando; resulta um valor com todos os bits
invertidos.
• A aplicação do operador ~ duas vezes no mesmo
operando resulta sempre o número original.
• Exemplo:
int main (){
unsigned char ch;
while((ch=getch()) != „X‟)
printf(“%c”, ~ch);
system(“PAUSE”);
return 0;
}
19. Operador de deslocamento
esquerdo: << e <<=
• Trata-se de um operador binário, mas que age somente no
operando da esquerda.
• Executa um deslocamento para a esquerda, conforme o
número de posições especificado no segundo operando.
• Toda vez que empurramos um bit à esquerda estaremos
multiplicando o número por dois.
X <<= 1; //é o mesmo que x*=2;
X <<= 2; //é o mesmo que x*=4;
• Exemplo:
20. Operador de deslocamento
esquerdo: << e <<=
int palavra () {
unsigned int n = ~0;
int i;
for( i=0; n; i++)
n <<= 1;
return i;
}
int main(){
int t = palavra();
printf(“O tamanho da palvra dessa máquina é %d
bits. n”, t);
system(“PAUSE”);
return 0;
}
21. Operador de deslocamento
esquerdo: >> e >>=
• É um operador binário, mas que age
somente no operando da esquerda.
• Executa um deslocamento para a
direita, conforme o número de
posições especificado no segundo
operando.
• Toda vez que empurramos um bit à
direita estaremos dividindo o número
por 2.
X >>= 1; //é o mesmo que x /= 2
22. Operadores de atribuição sobre
bits
&=
Operador de atribuição sobre bits AND.
|=
Operador de atribuição sobre bits OR inclusivo.
^=
Operador de atribuição sobre bits OR exclusivo.
<<=
Operador de alinhamento à esquerda com atribuição.
>>=
Operador de alinhamento à direita com atribuição.
23. Precedência e associatividade de operadores
Operadores
Associatividade
Tipo
() [] .
Esquerda para a direita
Mais alto
+ - ++ -- | & * ~sizeof (tipo)
Direita para a direita
Unário
*/%
Esquerda para a direita
Multiplicativo
+-
Esquerda para a direita
Aditivo
<< >>
Esquerda para a direita
Deslocamento
< <= > >=
Esquerda para a direita
Relacional
== !=
Esquerda para a direita
Igualdade
&
Esquerda para a direita
AND sobre bits
^
Esquerda para a direita
OR sobre bits
|
Esquerda para a direita
OR sobre bits
&&
Esquerda para a direita
AND lógico
||
Esquerda para a direita
OR lógico
?:
Direita para a direita
Condicional
= += -= *= /= |= ^= <<= >>= %=
Direita para a direita
Atribuição
,
Esquerda para a direita
vírgula
24. Campos de Bits
• C permite que o número de bits de um
membro UNSIGNED ou INT de uma
estrutura ou união armazenado, seja
especificado pelo programador.
• Campos de bits permitem uma utilização
da
memória
mais
competente,
armazenando dados no número mínimo
de bits exigido.
• Os membros de campo de bit DEVEM ser
25. Campos de Bits
struct bitCar {
unsigned face : 4;
unsigned suit : 2;
unsigned color : 1;
}; //jogo de cartas
• Um campo de bit é declarado ao se colocar um nome de
membro UNSIGNED ou INT seguido por um sinal de doispontos ( : ) e uma constante inteira representando a
largura do campo.
• A constante que representa a largura precisa ser um inteiro
entre 0 e o número total de bits usados para armazenar um
INT inclusive em seu sistema.
26. Campos de Bits
• O membro face é armazenado em 4 bits, o
membro suit é armazenado em 2 bits e o
membro color é armazenado em 1 bit.
• O número de bits é baseado no intervalo de
valores desejado para cada membro da
estrutura.
• 4 bits podem armazenar valores no intervalo
de 0 a 15;
• 2 bits podem armazenar valores no intervalo 0
a 3;
27. Campos de Bits
• O membro face armazena as cartas de ÁS até Rei;
• O membro suit armazena as cartas:
– Ouros = 0
– Copas = 1
– Paus = 2
– Espadas = 3
• O membro color armazena as cartas vermelho ou
preto.
28. Campos de Bits
• Membros de campo de bit das estruturas são
acessados exatamente como qualquer outro
membro da estrutura.
• É possível especificar um campo de bit não
nomeado para ser usado como preenchimento na
estrutura.
29. Exemplo 1
//converte hexadecimal
para binário
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int palavra();
int main(){
int t, j, num, bit;
unsigned int mask;
while(1){
t = palavra();
//1 no bit mais
significativo e zero nos
outros
mask = pow(2, t-1);
printf(" n Digite um
número em hexadecimal:
");
fflush(stdout);
scanf("%x", &num);
printf("Binário de
%04x é: ", num);
fflush(stdout);
for( j=0; j<t; j++){
30. Exemplo 1
bit = (mask & num) ? 1 : 0;
printf("%d", bit);
fflush(stdout);
if(((j+1)%8) == 0){
printf("--");
fflush(stdout);
}
mask >>= 1;
}
}
system("PAUSE");
return 0;
}
int palavra(){
unsigned int n=~0;
int i;
for( i=0; n; i++){
n <<= 1;
}
return i;
}