Como ninguém abordou o assunto de por que eles são úteis:
Uso muito operações bit a bit ao trabalhar com sinalizadores. Por exemplo, se você quiser passar uma série de sinalizadores para uma operação (por exemplo File.Open()
, com o modo de Leitura e o modo de Gravação ambos ativados), poderá transmiti-los como um valor único. Isso é feito atribuindo a cada sinalizador possível seu próprio bit em um conjunto de bits (byte, short, int ou long). Por exemplo:
Read: 00000001
Write: 00000010
Portanto, se você deseja passar para ler e escrever, você passaria (READ | WRITE) que combina os dois em
00000011
Que então pode ser descriptografado na outra extremidade, como:
if ((flag & Read) != 0) { //...
que verifica
00000011 &
00000001
que retorna
00000001
que não é 0, portanto, o sinalizador especifica READ.
Você pode usar o XOR para alternar vários bits. Eu usei isso ao usar um sinalizador para especificar entradas direcionais (Cima, Baixo, Esquerda, Direita). Por exemplo, se um sprite está se movendo horizontalmente, e eu quero que ele gire:
Up: 00000001
Down: 00000010
Left: 00000100
Right: 00001000
Current: 00000100
Simplesmente XOR o valor atual com (ESQUERDA | DIREITA) que desativará ESQUERDA e DIREITA, neste caso.
A troca de bits é útil em vários casos.
x << y
é o mesmo que
x * 2 anos
se você precisar multiplicar rapidamente por uma potência de dois, mas esteja atento para mudar um bit para o bit superior - isso torna o número negativo, a menos que não seja assinado. Também é útil ao lidar com diferentes tamanhos de dados. Por exemplo, lendo um número inteiro de quatro bytes:
int val = (A << 24) | (B << 16) | (C << 8) | D;
Supondo que A seja o byte mais significativo e D seja o menos. Terminaria como:
A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011
As cores geralmente são armazenadas dessa maneira (com o byte mais significativo ignorado ou usado como Alpha):
A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000
Para encontrar os valores novamente, basta mudar os bits para a direita até que estejam na parte inferior e depois mascarar os bits restantes de ordem superior:
Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF
0xFF
é o mesmo que 11111111
. Então, essencialmente, para Red, você faria o seguinte:
Color >> 16 = (filled in 00000000 00000000)11111111 00010101 (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)