[Tutorial] Operadores bit a bit
#1

Olб, neste tutorial vou ensinar como funciona os operadores bit a bit

1є Para que servem?
Operadores "bitwise", аs vezes traduzidos como "bit-a-bit", servem pra fazer operaзхes com bits. Enquanto operadores lуgicos avaliam cada lado da operaзгo apenas como verdadeiro ou falso, operaзхes bit-a-bit geram um valor numйrico entre os dois lados da operaзгo.


2є O que й um bit?
Um bit й a unidade mais pequena que pode ser representada num computador, um bit sу pode conter dois valores, 0 (zero) ou 1 (um). Os bits podem ser agrupados, sendo que, 8 bits correspondem a 1byte, 1024 bytes equivalem a 1 kilobyte, 1024 kilobytes representam 1 Megabyte, etc.


3є Operador AND (&)
Bruno da Silva jб fez um tutorial sobre ele bem explicado, que explica sobre binбrios tambйm, mas qualquer dъvida pode perguntar aqui se quiser.
https://sampforum.blast.hk/showthread.php?tid=352783


4є Operador OR (|)
O operador OR "|" compara dois valores utilizando suas representaзхes binбrias, para uma expressгo ser verdadeira pelo menos um dos bits tem que ser 1, entгo a expressгo sу serб falsa caso os dois bits forem igual a 0.

Vejam a tabela da verdade e gravem essas regras para este operador:
Код:
A   B   A|B
1   1    1
1   0    1
0   1    1
0   0    0
http://pt.wikipedia.org/wiki/Tabela_verdade

Como puderam ver o operador OR sу retorna falso caso os dois bits sejam 0.
Resultados aqui no pawn:
PHP код:
printf("%d"1); // = 1
printf("%d"1); // = 1
printf("%d"0); // = 1
printf("%d"0); // = 0 
Mesmo no tуpico do Bruno ensinando pode ter pessoas que ficaram com dъvidas entгo vou explicar de novo aqui...
E se o os nъmeros usados forem diferente de 1 e 0? Como 8 e 5?
PHP код:
printf("%d"5); 
Simples , basta pegar o valor binбrio de 8 e 5, entгo vamos lб.

Код:
8 -> 1000
5 -> 0101
Agora sу usar a regra da tabela da verdade e fazer a checagem dos bits.
Код:
8   5   8|5
1   0    1
0   1    1
0   0    0
0   1    1
Resultado: 1101
Agora o operador transforma os nъmeros binбrios em decimal que й igual a 13.
Entгo 8|5 = 13.

Espero que tenham entendido sobre o OR.
Os operadores bit a bit basicamente sу mudam a regra!


5є Operador XOR(^)
Como dito acima os operadores fazem basicamente a mesma funзгo, o que muda й a regra de cada um.
O operador XOR representado pelo ^ (acento circunflexo) compara dois valores binбrios exatamente como o OR, AND e outros.
A diferenзa й na regra, para uma expressгo ser positiva somente UM dos bits tem que ser 1.
"A conjunзгo й verdadeira se, e somente se, apenas um dos operandos for verdadeiro". Estб escrito no site da tabela da verdade. Lembrando que isso serve para o operador XOR!

Regra:
Код:
A   B   A^B
1   1   0
1   0   1
0   1   1
0   0   0
Resultados no pawn:
PHP код:
printf("%d"1); // = 0
printf("%d"1); // = 1
printf("%d"0); // = 1
printf("%d"0); // = 0 
Vou ensinar mais uma vez como fazer quando os valores forem diferente de 1 e 0, como por exemplo 11 e 7;
Por exemplo:
PHP код:
printf("%d"11^7); 
O operador vai transformar esses valores em binбrios, faz a checagem bit por bit e retorna o valor inteiro.
Entгo vamos lб:
Код:
11 -> 1011
7 -> 0111
Agora basta aplicar a regra do operador XOR
Код:
11   7   11^7
1    0   1
0    1   1
1    1   0
1    1   0
Resultado: 1100
Agora o operador converte o 1100 para inteiro que й o mesmo que 12.

Entгo 11^7 = 12.

Viu como й simples?


6є Agora vamos entrar em uma parte um pouco mais complicada... vamos falar dos operadores Shifts (<< e >>).

7є O que sгo os operadores Shifts?
O operador Shift desloca N bits а esquerda ou direita dependendo se for utilizado Shift Left(<<) ou Shift Right(>>). Devido а rapidez, sгo muitas vezes usadas na programaзгo como multiplicador ou divisor como substituiзгo dos operadores "*" e "/".


8є Shift Left(Deslocamento de bits б esquerda)
O operador Shift Left desloca а esquerda N bits. Pode-se entender o shift left como uma multiplicaзгo por 2 elevado a N. Й de salientar que um nъmero elevado a 0 й igual a 1, logo, o shift left de 0 equivale а multiplicaзгo por 1.

Resultado de testes no pawn usando nъmeros binбrios para melhor entendimento:
PHP код:
printf("%b"1011 << 1); // = 0110
printf("%b"1011 << 2); // = 1100
printf("%b"1011 << 3); // = 1000
printf("%b"1011 << 4); // = 0000 
*Obs: Estou usando %b para retornar valores binбrios, se vocк fizer o teste verб que irб retornar um valor muito maior, mas NESTE caso basta pegar os ъltimos quatro nъmeros
Resumindo, ele empurra os bits e vai adicionando um 0.

Agora vamos usar valores decimais no pawn:
PHP код:
printf("%d"<< 1); // = 10
printf("%d"<< 2); // = 20
printf("%d"<< 3); // = 40
printf("%d"<< 4); // = 80
printf("%d"<< 5); // = 160 
Acho que deu pra perceber que ele multiplica o 5 por 2 N vezes. Exemplo:
5 << 1 = 5*2 = 10
5 << 2 = 5*2*2 = 20
5 << 3 = 5*2*2*2 = 40
5 << 4 = 5*2*2*2*2 = 80
5 << 5 = 5*2*2*2*2*2 = 160

O mesmo serve para outros valores por exemplo:
10 << 3 = 10*2*2*2 = 80

Vocкs devem estar se pergunto, mas pra que eu vou usar isso?
Operadores Shifts sгo muito rбpidos, mais rбpidos que os operadores de multiplicaзгo e divisгo "*" e "/", por isso sempre que puder й bom usб-los. Tem esse exemplo tambйm no tutorial de optimizaзгo do Bruno da Silva:

Quote:
Originally Posted by ipsBruno
Caso vocк esteja usando:
PHP код:
floatpower(240); 
й muito mais optimizado vocк usar
PHP код:
<< 40 
Espero que tenham entendido!


9є Shift Right(Deslocamento de bits б direita)
Como vocкs viram o Shift Left pode-se entender como uma multiplicaзгo por 2 elevado a N, jб o Shift Right й ao contrario, ao invйs dele multiplicar ele faz a divisгo por 2 elevado a N.

Resultado dos testes no pawn usando binбrios:
PHP код:
printf("%b"1010 >> 1);// = 0101
printf("%b"1010 >> 2);// = 0010
printf("%b"1010 >> 3);// = 0001
printf("%b"1010 >> 4);// = 0000 
Peguei exemplo de um site para vocкs entenderem melhor!
PHP код:
new 10101011;
>> 10101011;
>> 01010101;
>> 00101010;
>> 00010101;
>> 00001010;
>> 00000101;
(...) 
Agora olhem os testes com nъmeros decimais:
PHP код:
printf("%d"60 >> 1); // = 30
printf("%d"60 >> 2); // = 15
printf("%d"60 >> 3); // = 7
printf("%d"60 >> 4); // = 3
printf("%d"60 >> 5); // = 1 
Entendendo:
60 >> 1 = 60/2
60 >> 2 = 60/2/2
60 >> 3 = 60/2/2/2
E assim por diante...


10є Diferenзa entre >> e >>>
Pelo o que eu andei lendo a diferenзa nгo й muita mas й fundamental.

Se vocк tem esse valor abaixo que й -10 convertido em binбrio por exemplo:
PHP код:
11110110// -10 
e vocк deseja usar deslocar os bits dele entгo vocк vai lб e faz:
PHP код:
11110110 >> 
O resultado vai ser 01111011 que ao invйs de ser -5 й 123, porque o operador >> nгo preenche a esquerda com o bit do sinal, ele sempre vai preencher com 0.

Agora se vocк fizer:
PHP код:
11110110 >>> 
O resultado vai ser 11111011 que й igual a -5, como podem ver ele preencheu a esquerda com 1 que era o bit antigo e nгo o 0 como faz o >>.


11є Complemento para dois (binбrios negativos)
Falando com o Stewie' no MSN, ele me explicou sobre transformar um valor inteiro positivo em negativo pela representaзгo binбria do mesmo.

Й simples. Explicaзгo: tenho o nъmero 10, transformando em binбrio ele fica 1010, mas como o limite de dados й 8 bits(1 byte) completamos o valor, ficando: 00001010. Agora para descobrir o negativo invertemos os valores.

Positivo: 00001010
Negativo: 11110101


Assim temos o -10
Crйditos dessa parte ao Stewie' por ter me explicado


Sei que ficou grande mas tentei deixar o mais explicado possнvel, pode haver erros por que comecei a estudar sobre os operadores ontem a noite. Entгo qualquer erro me avisem por favor.

Abraзos!
Reply
#2

Muito bom, parabйns
Reply
#3

Gostei.
Reply
#4

Ficou bom, parabйns Bruno.

Outro ponto interessante que aprendi a pouco tempo й que deslocando bits para direita com valor negativo -1 ele tende a retornar 0 para positivo de -1 para negativo.

10 >> -1 = 0
-10 >> -1 = -1
Reply
#5

Vlw Bruno pela dica =D
Obrigado humildade e Fire, que bom que gostaram
Reply
#6

http://pt.wikipedia.org/wiki/Complemento_para_dois
Reply
#7

Quote:
Originally Posted by Stewie`
Посмотреть сообщение
@Edit
Ah ta, falei contigo jб entendi, й uma explicaзгo sobre nъmero binбrio negativo para inteiros, para explicar melhor o que o Bruno disse!
Reply
#8

Parabйns, REP += 5.
Reply
#9

Vlw Paulor =D
Reply
#10

Excelente Bruno, perfeitamente explicado, organizado.
Parabйns. +rep
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)