Complemento de dois

Complemento de dois: funcionamento e exemplos Deixe um comentário

Nem sempre nós encontramos as bibliotecas dos CIs que precisamos utilizar em um projeto, e na hora de ler o datasheet para usá-lo, podemos nos deparar com alguns formatos numéricos que não conhecemos. Um desses formatos muito utilizados é o chamado complemento de dois, que explicaremos neste artigo.

Por que precisamos de formatos numéricos?

Antes de tudo, precisamos da resposta desta pergunta.
Todos os números no mundo da eletrônica digital, onde inclui-se o Arduino, Raspberry e até seu computador, são expressos por bits, ou seja, 1 e 0. Para conseguir trabalhar com um número como conhecemos no formato decimal, o processador de seu dispositivo precisa deste número em binário. Porém fica uma dúvida: e os números negativos? Como representá-los sendo que sempre vemos os números binários representando número positivos? Como por exemplo, 1 0 0 12 = 2³ + 2º = 8 + 1 = 9.

Como representar números negativos?

Uma das formas de representar números negativos e positivos utilizando números binários é o chamado “complemento de dois”. A teoria por trás dele é muito simples, para obter a representação negativa de um número você deve:

1) Inverter todos os bits do seu número;

2) Somar 1.

E como o sistema sabe que queremos expressar um valor negativo ao invés de positivo? Simples: sempre que o número for negativo, o bit mais significativo (MSB, ou bit mais à esquerda) será 1. Caso contrário, o número é positivo.
Confuso? Vamos tomar por exemplo o número 9 em binário (1 0 0 12) e assumir que ele seja um valor expresso no formato do complemento de dois. Vejamos a seguinte imagem:

Explicando o complemento de dois

Seguindo as setas da esquerda para a direita passamos de binário para decimal: vemos que o MSB é 1, então pegamos o valor 1 0 0 12 e invertemos seus bits, obtendo 0 1 1 02. Após isso, somamos 1, tendo assim 0 1 1 12 como resultado final, que convertido para decimal, vale 7. Mas como sabemos que este número é a representação de um valor usando complemento de dois, sabemos que seu valor é negativo, portanto, -7.
E ainda dá pra fazer o caminho contrário! Se formos da direita para a esquerda temos o seguinte: temos o número -7 e queremos representá-lo em binário no formato de complemento de dois. Convertemos o número 7 em binário, obtendo 0 1 1 12 e subtraímos 1, o que nos retorna 0 1 1 02. Invertemos os bits, o que resulta em 1 0 0 12. Veja que chegamos em um número com o MSB valendo 1, o que nos sinaliza que é um número negativo.
A tabela a seguir mostra todos os valores possíveis de 4 bits representados em binário, hexadecimal, decimal e complemento de dois.

Tabela explicando o complemento de dois

Observe que utilizando o complemento de dois conseguimos representar valores menores (em módulo) do que utilizando o formato decimal apenas. Ao invés de ir de 0 a 15, só podemos ir de 0 a 7 e de -1 a -8: é por isso que a variável do tipo uint_8t (o u significa unsigned, ou “sem sinal”) assume valores de 0 a 255 e a do tipo int_8t vai de -128 a 127 (signed type, ou “tipo com sinal). E é justamente este “u” na frente que indica para o compilador do código que usaremos o formato do complemento de dois!
Uma curiosidade: este formato é utilizado por processadores para fazer subtrações! Observe o exemplo abaixo:exemplo de uso do complemento de dois

Onde mais o complemento de dois é usado?

Embora isso seja usado nos programas que você escreve para o seu Arduino e você talvez nem soubesse (agora sabe a teoria por trás das variáveis uint_ e int_) vários sensores utilizam este formato para expressar seus resultados, pois isto torna muito mais ágil a conversão e operação com os números (como por exemplo as contas que precisamos fazer para converter a temperatura de Celsius para Fahrenheit). Um exemplo é o sensor de temperatura MAX31875 da Maxim. Dando uma olhada no datasheet (página 9) dele vemos como ele representa a temperatura medida:

exemplo de uso do complemento de dois 2

Veja que o último bit (B15) do registrador de temperatura é responsável pelo sinal da temperatura. Para interpretar a temperatura, vamos por exemplo assumir que lemos o valor 1 1 1 1 0 1 0 0 0 0 1 12 (ignoramos os bits que são sempre zero) no formato normal (última linha). Temos o MSB igual a 1, portanto precisamos converter este valor negativo. Convertendo temos:

1) Inversão dos bits: 0 0 0 0 1 0 1 1 1 1 0 02

2) Soma 1:  0 0 0 0 1 0 1 1 1 1 0 12

3) Convertendo para decimal usando a Tabela 3 do datasheet: – (8 + 2 + 1 + 0,5 + 0,25 + 0,0625) = -11,8125 °C

Agora se você se deparar com algum sensor que utilize este formato e não tenha biblioteca pronta, você será capaz de ler os valores dele sem problema e exibir o valor certo no seu display, terminal ou smatphone.

Gostou de aprender sobre o complemento de dois? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Posts Relacionados

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *