[SP-pm] Operadores Bit-a-Bit (Bitwise)

breno breno at rio.pm.org
Mon May 31 10:30:14 PDT 2010


http://perl.org.br/Artigos/Operadoresbit-a-bit

Odeio vocês todos.

:-)

[]s

-b

obs: as tabelas ficaram muito comprimidas, não consegui forçar o
espaçamento. Se alguém quiser tentar, fique à vontade.

2010/5/31 Andre Carneiro <andregarciacarneiro em gmail.com>:
> Breno++ # Excelente explicação! Concordo com a opinião do Nelson de que
> deveria virar um artigo, mesmo porque não existe muito material bom em
> português sobre isso( eu pelo menos nunca vi um que prestasse, o seu é o
> primeiro ). Parabéns!
>
> Cheersr!
>
> Em 31 de maio de 2010 08:14, "Flávio R. Lopes" <flavio.lopes em links.inf.br>
> escreveu:
>>
>> Olá Breno!
>> Cara!...isto foi uma aula!...Obrigado pela ótima explicação!
>> Mas como você disse, isto ainda não é para mim!...Quem sabe algum dia em
>> algum caso específico!
>>
>> Já até arquivei este e-mail!
>>
>> Abraço,
>> Flávio
>>
>> Em 31-05-2010 04:08, breno escreveu:
>>>
>>> 2010/5/31 "Flávio R. Lopes"<flavio.lopes em links.inf.br>:
>>>
>>>>
>>>> Boa noite pessoal.
>>>> Ainda seguindo nos meus estudos, me deparei com um capítulo que trata
>>>> dos
>>>> "Bitwise Operators".
>>>> Achei "meio complicado" !!!
>>>>
>>>> Parecem-se muito com os comparadores lógicos
>>>>
>>>> Enfim, ONDE isto é usado ou PARA QUE isto é usado?
>>>>
>>>>
>>>
>>> Resposta curta: se vc realmente não tem idéia do que é ou pra que é
>>> usado, vc não precisa disso. Pule e seja feliz :-)
>>>
>>> É sério. Algumas linguagens de programação são minimalistas e voltadas
>>> para um tipo de problema específico. Perl 5 é uma linguagem complexa e
>>> de uso geral, o que significa que foi especialmente projetada para
>>> resolver uma série de problemas. Pense em Perl como uma lingua. Você
>>> sabe português, não sabe? O que é um "camote"? Ou um "extrário"?
>>> "Oligolécito"? Não sabe? Pois é, nem eu. E não precisei nem procurar
>>> muito: abri o dicionário aqui em 3 páginas aleatórias e elas estavam
>>> lá. Quando vi pensei "aaahhhhnnnn ok", e agora que estou escrevendo,
>>> já fiz questão de esquecê-las novamente. Não fazem parte do meu
>>> vocabulário pq não preciso delas. O dia que surgirem, peço licença,
>>> olho o "pai dos burros" e sigo em frente. Perl (e outras linguagens
>>> verborrágicas) são assim também. Um dia você olha um código chamando
>>> uma função que não conhece, e perldoc nela. Ou, se um dia tiver um
>>> problema qualquer, uma busca simples por palavras chaves (ou em listas
>>> como essas) te apontará para esse tipo de conhecimento e
>>> funções/módulos associados. Então, não perca tempo tentando saber
>>> tudo. Com tanta informação no mundo, precisamos escolher sabiamente
>>> com o que ocupar a mente ;-)
>>>
>>> Resposta longa: Como vc achou "meio complicado", vou começar a
>>> resposta do ONDE e PRA QUE com "O QUE". 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.
>>>
>>> Em computadores, seus dados são armazenados em grandes coleções de
>>> zeros e uns, os bits. Números decimais, por exemplo, são representados
>>> em forma binária (base 2, números compostos apenas por bits):
>>>
>>> 0 =>          0
>>> 1 =>          1
>>> 2 =>        10
>>> 3 =>        11
>>> 4 =>      100
>>> 5 =>      101
>>> 6 =>      110
>>> 7 =>      111
>>> 8 =>    1000
>>> 9 =>    1001
>>> 10 =>  1010
>>> 11 =>  1011
>>> 12 =>  1100
>>> 13 =>  1101
>>> 14 =>  1110
>>> 15 =>  1111
>>>
>>> e assim por diante.
>>>
>>> As operações desse tipo são feitas bit-a-bit. Vejamos como exemplo a
>>> operação "E" (AND), que é 1 apenas se os dois bits avaliados forem 1,
>>> e 0 caso contrário. Assim, ao fazermos "3&  14", estamos calculando na
>>> verdade "0011&  1110" (veja tabela acima). Isso fará uma comparação
>>> (da esquerda pra direita) de 0 com 1 (resultando em 0), depois de 0
>>> com 1 novamente (0), depois de 1 com 1 (resultando em 1) e finalmente,
>>> de 1 com 0 (0). O valor final, portanto, será "0010", ou seja, "2" (na
>>> base decimal):
>>>
>>>    0 0 1 1
>>> &  1 1 1 0
>>> --------------
>>>    0 0 1 0
>>>
>>> As operações mais comuns entre dois valores são E (AND), OU (OR), e OU
>>> EXCLUSIVO (XOR), que podem ser representados pelas seguintes
>>> tabelas-verdade (observe cada linha para combinações de bits em $p e
>>> $q, e para o bit resultante da operação entre eles):
>>>
>>>       E (AND)
>>> --------------------------
>>> $p ,  $q ,  $p&  $q
>>>   0 ,    0 ,      0
>>>   0 ,    1 ,      0
>>>   1 ,    0 ,      0
>>>   1 ,    1 ,      1
>>>
>>>
>>>       OU (OR)
>>> --------------------------
>>> $p ,  $q ,  $p | $q
>>>   0 ,    0 ,      0
>>>   0 ,    1 ,      1
>>>   1 ,    0 ,      1
>>>   1 ,    1 ,      1
>>>
>>>
>>> OU EXCLUSIVO (XOR)
>>> --------------------------
>>> $p ,  $q ,  $p ^ $q
>>>   0 ,    0 ,      0
>>>   0 ,    1 ,      1
>>>   1 ,    0 ,      1
>>>   1 ,    1 ,      0
>>>
>>>
>>> Há ainda o NÃO (NOT), que inverte todos os bits do elemento:
>>>
>>> $p   ~$p
>>>  0     1
>>>  1     0
>>>
>>>
>>> Agora, de volta à sua pergunta original:
>>>
>>> Operações bit a bit são muito utilizadas na manipulação de dados
>>> binários (imagens, criptografia, etc) e quando espaço é um problema
>>> (como alguns sistemas embutidos ou operações em massa). Dois exemplos
>>> pra vc:
>>>
>>> 1) Máscaras de rede são números de 32 bits usados pra separar a parte
>>> correspondente à rede pública, à subrede e aos hosts. Quando dizemos
>>> que uma subrede tem máscara 255.255.255.0, estamos fazendo uma
>>> operação binária AND entre esse valor
>>> (11111111.11111111.11111111.00000000) e o valor da rede, também em
>>> binário.
>>>
>>> 2) Quando temos valores que podem ser apenas verdadeiro ou falso
>>> (também chamados de flags), podemos otimizar o espaço ocupado
>>> atribuindo um bit para cada flag. Por exemplo:
>>>
>>> POSSUI_FOO = 0001
>>> POSSUI_BAR = 0010
>>> POSSUI_BAZ  = 0100
>>> POSSUI_MEH = 1000
>>>
>>> Assim, não nos importamos com o valor decimal resultante mas sim com
>>> quais flags estão ativas. O valor 1001, por exemplo, possui apenas as
>>> flags "FOO" e "MEH" ativas. Note que, conforme nossa representação
>>> binário-decimal, cada bit ativo pode ser representado por uma potência
>>> de 2:
>>>
>>> 0001 == 1 == 2**0
>>> 0010 == 2 == 2**1
>>> 0100 == 4 == 2**2
>>> 1000 == 8 == 2**3
>>>
>>> etc.
>>>
>>> Uma rápida olhada em nossas tabelas verdade e vemos que podemos
>>> atribuir flags através de OR:
>>>
>>> my $flags = 0;
>>> my ($IS_FOO, $IS_BAR, $IS_BAZ, $IS_MEH) = (1, 2, 4, 8);
>>>
>>> $flags = $flags | $IS_FOO;  # ativa a flag 'FOO'
>>> $flags = $flags | $IS_BAZ;   # ativa a flag 'BAZ'
>>>
>>> e testar cada flag através de um AND:
>>>
>>> # flag 'FOO' está ativa?
>>> if ( $flags&  $IS_FOO ) {
>>>   ...
>>> }
>>>
>>> Pacotes IPv4 e outras estruturas de dados que precisam de otimização
>>> de espaço usam isso, já que dessa forma não precisam reservar um (ou
>>> mais) bytes para cada flag.
>>>
>>> Esse tipo de cenário pode ser encontrado até fora de ambientes
>>> computacionais, como uma prova de concurso com N afirmativas valendo
>>> 1, 2, 4, 8, 16, 32 e que pede ao aluno pra dizer a soma das
>>> afirmativas corretas (OR).
>>>
>>>
>>> É isso. Mas não se acostume, esse é o tipo de pergunta cuja resposta
>>> pode ser facilmente encontrada aqui:
>>>
>>> http://tinyurl.com/2aggysf
>>>
>>>
>>> []s
>>>
>>> -b
>>> _______________________________________________
>>> SaoPaulo-pm mailing list
>>> SaoPaulo-pm em pm.org
>>> http://mail.pm.org/mailman/listinfo/saopaulo-pm
>>>
>>>
>>
>> _______________________________________________
>> SaoPaulo-pm mailing list
>> SaoPaulo-pm em pm.org
>> http://mail.pm.org/mailman/listinfo/saopaulo-pm
>
>
>
> --
> André Garcia Carneiro
> Analista/Desenvolvedor Perl
> (11)82907780
>
> _______________________________________________
> SaoPaulo-pm mailing list
> SaoPaulo-pm em pm.org
> http://mail.pm.org/mailman/listinfo/saopaulo-pm
>


More information about the SaoPaulo-pm mailing list