Golang brincando com bits
Brincando com bits
A ideia é manipular a paleta de cores do CGA que armazena as cores em um unico byte, essa brincadeira parece complicada mas na verdade é muito simples, precisamos apenas aprender algumas poucas operações para poder manipular bits.
Antes de começarmos vamos combinar o seguinte, quando eu falar sobre a parte superior ou alta de um conjunto de bits estou me referindo aos bits mais a esquerda, e quando estiver falando da parte inferior ou parte baixa estou falando dos bits mais a direita. Nem sempre é assim, mas para efeito desse texto é assim que funciona é o que chamamos de lite-endian
Shift (« e », desloca bits)
Shift é o operador para movre bits para direita « ou esquerda »
Exemplo
00000001 << 1 resulta em: 00000010
00000001 << 2 resulta em: 00000100
00000001 << 3 resulta em: 00001000
10000000 << 1 resulta em: 01000000
10000000 << 2 resulta em: 00100000
10000000 << 3 resulta em: 00010000
AND (&)
Usamos end para definir uma mascara e usamos essa mascara para extrair a parte que queremos de um conjunto de bits.
Exemplo
Digamos que queremos extrair apenas os quatro bits centrais de um byte, para isso definimos a seguinte mascara: 00111100 note que os bits que queremos extrair estão com 1 e os que não queremos estão com 0. Daí basta comparar o byte que contem o valor a ser extraído com a mascara usando AND (&)
valor & mascara
10101010 & 00111100 resulta em: 00101000
O que and faz é comparar cada um dos bits com o seu correspondente na mascara e apenas onde os dois bits forem 1 vai ser 1 no resultado. Com isso os outros bits fora da mascara foram zerados.
E agora podemos usar shift para a direita , andar duas casas e obter o valor que queremos extrair em um byte.
00101000 >> 2 resulta em: 00001010
Ou seja usamos AND junto com uma mascara de bits para separar as partes que queremos de um conjunto de bits.
OR (|)
OR nesse caso é o inverso, usaremos para combinar dois conjuntos de bits em um único.
Exemplo
Digamos que queremos juntar esses quatro bits 1010 na parte superior de um byte seguido desses 4 bits 0101 na parte inferior.
Primeiro movemos os 4 bits para a parte superior do byte:
00001010 << 4 resulta em: 10100000
Daí usamos OR para juntar a parte superior e a inferior:
10100000 | 00000101 resulta em: 10100101
Vamos ver um exemplo em Go:
package main
import "fmt"
func main() {
/*
Pega os códigos da cor da fonte e do fundo
e combina os dois em um único byte
*/
var b, f byte
b = 0x9 // cor do fundo (azul claro)
f = 0x4 // cor da fonte (vermelho)
// combina os dois códigos para compor o código da cor
c := (f & 0x0f) | (b << 4)
/*
Pega o código da cor e separa a cor da fonte
e do fundo para poder usar separadamente
*/
h := (c & 0xf0) >> 4 // High Nibble
l := c & 0x0f // Low Nibble
blink := (c & 0x80) >> 7
/*
Mostra os resultados
*/
fmt.Printf("cor do fundo.: %04b\n", h)
fmt.Printf("cor da letra.: %04b\n", l)
fmt.Printf("codigo da cor: %08b\n", c)
fmt.Printf("blink........: %b", blink)
}