11/10/12
Página de Evy Salcedo
Física Computacional ­ FSC­5705
Súmula
Aulas
Lista
Conc.
Freq.
Outros
Ensino
Operações em nível de bits
O grande poder que o C dá ao programador fica explícito nos operadores de controle de bits. Os
operadores a seguir atuam sobre variáveis do tipo unsigned char, unsigned short, unsigned
int, unsigned long, ou seja, variáveis que possam representar inteiros sem sinal.
O operadores de controle de bit são &, |, ^, <<, >> e ~ os quais são e, o, o exclusivo,
deslocamento à direita, deslocamento a esquerda e complemento 1 (o qual é um operador
unário), respetivamente. O operador & é tal que:
operação
resultado
operação
resultado
operação
resultado
1&1
1
1|1
1
1^1
0
1&0
0
1|0
1
1^0
1
0&1
0
0|1
1
0^1
1
0&0
0
0|0
0
0^0
0
operação
resultado
~1
0
~0
1
Como exemplo consideremos o seguinte número binário 1 0 1 1 0 0 1 1. Esse é um número
com 8 bit e representa o número 179 em decimal, vejamos
N. Binario
→
1
0
1
1
0
0
1
∗
∗
∗
∗
∗
∗
∗
7
2
Fator de conversao
→
Resultado
→
128 +
N. decimal
→
179
6
2
0 +
5
2
32 +
4
2
16 +
3
2
0 +
2
2
0 +
1
2
2
1
∗
2
0
1
Esse mesmo número decimal representa a letra que é o 3 quando é elevado ao cubo um
numero. Par poder ver isso temos que ajustar nosso terminal para que imprima caráteres
representados por 8 bits, isto é colocar no formato iso 8859-15. Para fazer isso clicamos no
terminal (parte preta) com o botão direito do mouse e depois clicamos com o botão
esquerdo do mouse em Editar o perfil atual ... o que abre uma janela.
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
1/7
11/10/12
Página de Evy Salcedo
Nessa janela clicamos na aba Avançado. Na última linha dessa janela que é sobre codificação
clicamos em Selecionar, isso abre uma outra janela onde clicamos em Oeste Europeo, isso por
sua vez abre uma última janelinha onde escolhemos ISO 8859-15.
Colocado na codificação adequada, passamos a testar nosso operadores bit a bit. Mostramo
anteriormente que o número binário 1 0 1 1 0 0 1 1 é o número 179 que no padrão ISO 885915 (ASCII) representa o cubo (3). Isso pode ser visto no exemplo a seguir
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
2/7
11/10/12
Página de Evy Salcedo
No código acima é impresso atribuído o numero 179 a uma variável de tipo caráter e logo é
solicitado ao printf imprimir em tela sua representação em caráter (%c). Na linha 10 é colocado
o valor hexadecimal (colocando 0x para avisar ao C que é Hexadecimal) que equivale ao digito
binario 1 0 1 1 0 0 1 1. Para coverter o número de binario para Hexadecimal, dividimos o número
binário em conjuntos de quatro digitos. Com quatro bits o máximo número que da para
representar é o, 1111 → 15, como o sistema hexadecimal está constituído pelos dígitos {0, 1, 2,
3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F}, onde A → 10, B → 11 , C → 12 , D → 13 , E → 14 , F → 15 ,
resulta natural trabalhar nessa base. Uma vez dividido podemos converter para decimal cada
conjunto é substituir pelo seu equivalente hexadecimal. No exemplo acima temos os grupos
1011 → 11 → B e 0011 → 3 → 3, assim 10110011 → 0xB3
Decimal
Hexadecimal
Binary
0
0
0000
1
1
0001
2
2
0010
3
3
0011
4
4
0100
5
5
0101
6
6
0110
7
7
0111
8
8
1000
9
9
1001
10
A
1010
11
B
1011
12
C
1100
13
D
1101
14
E
1110
15
F
1111
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
3/7
11/10/12
Página de Evy Salcedo
Agora apliquemos o operador &. No exemplo acima foram feitas as seguintes atribuições
a ← 10110011 e a outra variável o número b ← 00000111 . Na linha 13 e realizada a operação
entre às duas variáveis e atribuída à variável c, 10110011 & 00000111 , o resultado dessa
operação é c ← 00000011 segundo a tabela. Convertendo para decimal obtemos:
7
6
5
4
3
2
1
0
0 ∗ 2 + 0 ∗ 2 + 0 ∗2 + 0 ∗ 2 + 0 ∗2 + 0 ∗2 + 1 ∗ 2 + 1 ∗2
= 3, que coincide com o valor
impresso na tela.
Neste
exemplo
é
analisado
10110011 | 00000111 → 10110111
7
1 ∗ 2
6
+ 0 ∗ 2
5
+ 1 ∗2
4
+ 1 ∗ 2
o
.
uso do operado
Convertendo
3
+ 0 ∗2
+ 1 ∗2
2
1
+ 1 ∗ 2
|.
A
para
0
+ 1 ∗2
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
operação
decimal
analisada
é
obtemos:
= 183
4/7
11/10/12
Página de Evy Salcedo
Neste exemplo é analisado o uso do operado ^. A operação analisada é
00000111 → 10110100.
Convertendo
para
decimal
7
1 ∗ 2
6
+ 0 ∗ 2
5
+ 1 ∗2
4
+ 1 ∗ 2
3
+ 0 ∗2
+ 1 ∗2
2
1
+ 0 ∗ 2
0
+ 0 ∗2
^
obtemos:
10110011
= 180
Neste exemplo é analisado o uso do operado ~. A operação analisada é ~10110011 →
01001100.
Convertendo
para
decimal
obtemos:
7
0 ∗ 2
6
+ 1 ∗ 2
5
+ 0 ∗2
4
+ 0 ∗ 2
3
+ 1 ∗2
+ 1 ∗2
2
1
+ 0 ∗ 2
0
+ 0 ∗2
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
= 76
5/7
11/10/12
Página de Evy Salcedo
Neste
exemplo
é
analisado o uso do operado <<. A operação
analisada é
. Esse comando deslocou à esquerda todos os bits assim o bit zero
passa para a posição 2, o 1 para posição 3, etc. O espaço deixado é preenchido com zeros.
Convertendo
para
decimal
obtemos:
7
6
5
4
3
2
1
0
1 ∗ 2 + 0 ∗ 2 + 0 ∗2 + 1 ∗ 2 + 1 ∗2 + 0 ∗2 + 0 ∗ 2 + 0 ∗2
= 152. Deve se ter claro que
o deslocamento de bits não é uma rotação, os bits que saem à esquerda são apagados e o
espaço que sobra à direita é preenchido com zero.
10110011 << 3 → 10011000
Neste
exemplo
é
analisado o uso do operado >>. A operação
analisada é
. Esse comando deslocou à direita todos os bits assim o bit 7 passa
para a posição 4, o 6 para posição 3, etc. O espaço deixado é preenchido com zeros.
Convertendo
para
decimal
obtemos:
7
6
5
4
3
2
1
0
0 ∗ 2 + 0 ∗ 2 + 0 ∗2 + 1 ∗ 2 + 0 ∗2 + 1 ∗2 + 1 ∗ 2 + 0 ∗2
= 22.
10110011 >> 3 → 00010110
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
6/7
11/10/12
Página de Evy Salcedo
Uma utilidade do deslocamento à direita é que pode servir como uma forma de multiplicar e
dividir muito rápida. No exemplo acima definimos uma variável a como sendo uma variável de
tipo unsigned long. Isso significa que não tem parte negativa (por isso unsigned) e tem
tamanho de 32 bits ou 4 bytes (4*8 = 32), como mostra o resultado de sizeof(a) (linha 7)
impresso na tela. Em a linha 9 assinamos o valor 100 à variável a; o qual é impresso na seguinte
linha. Observe que se está utilizando como descritor de formato a opção %lu, no lugar de %d. A
razão disso é que %lu diz para o printf que o número a ser impresso é do tipo unsigned (por isso
o u), mas é de 4 bytes ou seja é um long, dai o l no descritor. Na linha 12 é realizado um
deslocamento de uma posição à esquerda o que da como resultado que o nosso numero seja
multiplicado por 2, como é impresso na tela (resultante do printf da linha 13). Na linha 15
atribuímos o valor constante de tipo sem sinal inteiro longo à variável a. Na linha 18 realizamos
um deslocamento à esquerda do bits nessa variável e quando imprimimos vemos que o resultado
é a metade do valor, ou seja 150.
/media/ext4_evy/Ensino/UFSC/Ano2012/IIsemestre/public_html/…/aula110.html
7/7
Download

Física Computacional FSC5705