The Code Codex
Tema
← Notas / Fundamentos

nota · texto14 out 2024 · 2 min

Operações com binários

Todo inteiro é guardado em binário. Operações bit a bit (bitwise) comparam ou movem esses bits um a um, sem passar pela aritmética comum.

Exemplo com a = 12 (1100) e b = 10 (1010):

OperaçãoGoJavaRegraResultado
ANDa & ba & b1 se os dois bits são 11000 = 8
ORa | ba | b1 se pelo menos um é 11110 = 14
XORa ^ ba ^ b1 se os bits são diferentes0110 = 6
NOT^a~ainverte todos os bits-13
AND NOTa &^ ba & ~blimpa em a os bits ligados em b0100 = 4
Desloca à esquerdaa << 1a << 1multiplica por 211000 = 24
Desloca à direitaa >> 1a >> 1divide por 20110 = 6

Java ainda tem >>>, que desloca à direita preenchendo com zeros mesmo em números negativos. Em Go o mesmo efeito vem de usar tipos sem sinal (uint).

Onde aparece na prática

Flags e permissões: vários sim/não guardados em um único número. As permissões do Unix são isso: chmod 755 é 111 101 101 (dono lê, escreve, executa; grupo e outros leem e executam).

const (
Read = 1 << iota // 001
Write // 010
Exec // 100
)
perm := Read | Write // liga leitura e escrita: 011
canWrite := perm&Write != 0 // testa um bit: true
perm &^= Write // desliga a escrita: 001
static final int READ = 1, WRITE = 1 << 1, EXEC = 1 << 2;
int perm = READ | WRITE;
boolean canWrite = (perm & WRITE) != 0;
perm &= ~WRITE;

Truques rápidos: n & 1 diz se o número é ímpar; n & (n - 1) == 0 diz se é potência de 2 (para n > 0).

Máscaras: extrair parte de um valor, como o canal vermelho de uma cor 0xRRGGBB com (color >> 16) & 0xFF.

Veja também: Tipos de dados.