+2

Esmiuçando operadores bit-a-bit

criado por Alisson Carlos de F. Rodrigues em 24/12/2006 9:53pm
Além desses quatro operadores, ainda existe mais dois, que trato separadamente por funcionar de uma forma um pouco diferente. Neste caso não é feito comparação entre os dois elementos dados, temos (tirado do manual):

$a << $b - Desloca os bits de $a $b passos para a esquerda
$a >> $b - Desloca os bits de $a $b passos para a direita

Você deve estar se perguntando: “Pra que diabos eu vou usar essa coisa?”. Pois bem, vou tentar passar um exemplo prático, que está contido num script para transformar imagens coloridas em PB que eu postei no laboratório de scripts a pouco tempo.

A função imagecolorat() busca a cor de um determinado pixel numa imagem, e retorna um valor inteiro, mas não queremos este valor assim, portanto precisamos transforma-lo em binário para depois retornar o RGB.

Transformando este valor retornado em binário, vamos obter um número com 24 dígitos, cada 8 dígitos é uma das 3 cores RGB. Então, os 8 primeiros são Red, os 8 do meio Green, e os 8 últimos Blue. Nem preciso dizer que 8 números binários representam 1 byte, preciso? Pois é. Daí você pensa: “Obaaaaaaaaaaaaa, vou usar substr pra pegar essa informação”. Não não não, use operadores bit-a-bit.

Imagine que a funçãozinha ali retornou esse número:

111000000000000000000000

Legal, você quer pegar os 8 primeiros números, simples (nada de substr), você vai deslocar esses 8 números para a direita, tirando os 16 que estão do seu lado direito, portanto estes SOMEM, assim (14680064 é esse número grandão ali em cima em decimal):

$r = 14680064 >> 16;

Pronto, retorna 11100000 ou 224 em decimal.

Agora você quer pegar os 8 números do meio. Deve pegar novamente o número grandão e deslocar 8 números para a direita:

$g = (14680064 >> 8) & 0xFF;

Repare que dessa vez eu usei aquele operador bit-a-bit apresentado lá no começo, vamos analisar: você puxou os 16 primeiros números para direita, ou seja, excluiu os 8 últimos (o 8 do código ali), e está comparando com o valor 255 (FF em hexadecimal ou 11111111 em decimal), o operador “&” só vai ativar o que tiver nos dois números dados, portanto, no script abaixo, é excluído os 8 primeiros números (antes já havia sido excluído os 8 últimos).

1110000000000000
0000000011111111

Em lugar algum temos dois números “1”, portanto aqui vai ser retornado “0” simplesmente.

Só falta o blue, aqui nem precisamos deslocar bit algum, basta compararmos com 255:

$b = 14680064 & 0xFF;
Analisando:

111000000000000000000000
000000000000000011111111

Repare que novamente você não tem dois números “1” em lugar algum. Portanto, será retornado novamente 0. Então deu pra perceber que essa comparação com o número 255 serve somente pra excluir os primeiros dígitos, nos 8 últimos ele não altera nada.

Finalmente descobrimos o RGB, que é 224,0 e 0. Pra ficar mais fácil podemos transformar em hexadecimal, que é a maneira mais utilizada (não em PHP, a função imagecolorallocate por exemplo usa a primeira maneira como argumentos e transforma em um inteiro), usando a função dechex() do próprio PHP, assim obteríamos E0,0 e 0 ou simplesmente “E00000”.

Finalmente, chegamos ao fim desse gigante tutorial, espero que tenha ficado muito bem explicado e sirva para vocês não sofrerem tanto pra aprender quanto eu, já que não consegui encontrar nenhum material explicado assim, tive que ir na raça.

Abraços.

Comentários:

Mostrando 1 - 10 de 11 comentários
Gustavo disse:
O artigo é bem interessante. Curioso que, talvez pela característica de praticidade do php, poucos façam uso desse recurso.

Apenas para colaborar, é necessário observar a precedência dos operadores do exemplo:
if ($numeroRetornado & $numeroDaTecla == $numeroDaTecla)

O correto deveria ser:
if (($numeroRetornado & $numeroDaTecla) == $numeroDaTecla)

Isso porque '==' tem precedência maior que '&', logo se os valores de $numeroRetornado e $numeroDaTecla forem iguais entre si e diferentes de '1', o resultado será erradamente falso.

[]'s
06/05/2007 1:29pm (~17 anos atrás)

Muito bom, interessante as operações bit-a-bit, dão um ganho considerável de desempenho.É "estranho" utilizar esses operadores, mas creio que é uma questão de costume.

Meus parabéns
09/03/2007 4:15am (~17 anos atrás)

Já terminei a segunda parte do artigo e já enviei pro site, só falta os moderadores aceitarem.
06/03/2007 12:39pm (~17 anos atrás)

Talvez eu crie um segundo artigo ainda com alguns exemplos úteis e até alguns exercícios. t+
06/03/2007 5:47am (~17 anos atrás)

Foi bom cara...
Agora só preciso achar um modo de usar esses operadores.
Pois só fixo bem quando eu começo a fazer...
05/03/2007 10:40pm (~17 anos atrás)

Aqui na empresa usamos isso direto. E seu artigo foi fundamental para meu embasamento... !!
28/02/2007 10:38am (~18 anos atrás)

Pois é meu velho, respirando novos ares hehehe
26/01/2007 6:03pm (~18 anos atrás)

hinom disse:
olha quem tah aqui! alisson do imasters
25/01/2007 8:58pm (~18 anos atrás)

Bom Artigo!
Show de bola operadores bit a bit.
11/01/2007 8:51am (~18 anos atrás)

Bom artigo!
Isso tambem é materia para quem quer se certificar!
Valew!
09/01/2007 3:39am (~18 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)