Bitmask
Introdução
Um dos recursos mais utilizados por programadores em todos os tempos, extremamente rápido, eficiente e prático, chama-se bitmask.
Infelizmente tem sido consolidada a visão de que tudo que exige o conhecimento mínimo de programação é ruim, porque diminui a clareza do código. Em “diminui a clareza do código” leia: torna o código ilegível para programadores que não sabem programar… mas tudo bem. O coitado do bitmask sofreu com isso.
Trata-se de uma ferramenta muito legal para armazenar e comunicar estados compostos por n condições.
Em uma variável tipo byte (em java), você armazena até 7 informações de estado diferentes. Em um short são 15 informações. Sem quaisquer necessidades de computações mirabolantes adicionais.
Aliás se Java tivesse tipos numéricos sem sinais, poderíamos usar os 8 bits de cada byte. Mas isso é outra discussão.
A Mágica
Vamos imaginar que estamos vistoriando um carro, e queremos armazenar em uma variável byte as seguintes informações:
- O carro está com todos os 4 pneus em condições de uso;
- O carro possui combustível;
- O carro possui óleo de freio;
- O carro possui óleo de motor;
Atribua uma potência de 2 a cada informação que deseja armazenar, assim:
- 2ˆ0 = 1 -> O carro está com todos os 4 pneus em condições de uso;
- 2ˆ1 = 2 -> O carro possui combustível;
- 2ˆ2 = 4 -> O carro possui óleo de freio;
- 2ˆ3 = 8 -> O carro possui óleo de motor;
Crie uma variável “estadoDoCarro” e atribua a ela a soma das condições que correspondem a realidade do carro:
- 2ˆ0 = 1 -> O carro está com todos os 4 pneus em condições de uso;
- 2ˆ1 = 2 -> O carro possui combustível;
- 2ˆ2 = 4 -> O carro possui óleo de freio;
RESULTADO DA SOMA = 7
byte estadoDoCarro = 7;
Para verificar quais as condições satisfeitas basta utilizar o operador ‘&’:
byte b = 11;
if ((b & 1) != 0)
System.out.println("O carro está com todos os 4 pneus em condições de uso;");
if ((b & 2) != 0)
System.out.println("O carro possui combustível;");
if ((b & 4) != 0)
System.out.println("O carro possui óleo de freio;");
if ((b & 8 ) != 0)
System.out.println("O carro possui óleo de motor;");
Qual é o truque?
Utilizando as potências de 2 estamos “ligando/desligando” cada um dos bits, e “concatenando” booleans. Veja:
| Decimal | Binário |
| 0 | 0 |
| 1 | 1 |
| 2 | 10 |
| 4 | 100 |
| 8 | 1000 |
| 16 | 10000 |
Observações
- Em Java existe a classe java.util.BitSet que pode ser bastante útil para essas representações de estado;
- Outros operadores como o ‘|’ são úteis para esse tipo de técnica, e devem ser dominados por qualquer programador;
- Aqueles ifs acima podem ser facilmente substituidos por um loop;
- Cada um dos componentes (as potências de dois), normalmente deve ser armazenada em uma constante.
4 Responses to Bitmask
Deixe um Comentário Cancelar resposta
Assuntos
- Arquitetura (1)
- Geral (1)
- Java (5)
- Concorrência (1)
- I/O (1)
- Testes (1)






Numa aplicação com restrições de memória isso deve ser bastante útil!
Mas realmente fica bem menos legível! A semântica fica prejudicada!
Muito interessante!
Tem colocado isso em prática em algum projeto?
Se você organizar as constantes direitinho fica bem legível… Quando você vai transitar dados na rede pode ser interessante juntar as informações de estado. em um único valor.
Mas principalmente: Quando você vai interagir com a máquina, ou com outros sistemas, você eventualmente terá que usar, sem alternativas. Então é bom saber né…
Interessante! Não sabia que isso tinha um nome.
E é uma coisa que já é tão difundida há tanto tempo. Só lembrar daquelas provas onde a resposta é a soma dos números que representam questões verdadeiras.
Realmente não vejo por que ficaria ilegível. Só exige abstração.
Esqueci de mencionar que usei isso em Python algumas vezes no “motor” 3D com simulação de física. O cálculo de colisão pode ser muito bem feito com bitmask ao se verificar se um determinado objeto está tocando vários outros ou não, gerando assim vários estados. Entrando em colisão com chão e parede ao mesmo tempo, ou com o teto e uma janela e um vento com velocidade x, etc.