[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)
}

Teste no The Golang Playground

Cesar Gimenes