1. Introdução
Já vimos que, na representação de números binários, a posição em que um dígito 0 ou 1 está determina o valor daquele dígito. Para relembrar, retorne ao capítulo de Sistemas de Numeração, seção 1.4. Mas, até o momento, vimos apenas a representação de números positivos. Como representar, então, números negativos? Há algumas maneiras de fazer isso.
1.1. Bit do sinal
Uma das formas é usar o primeiro bit, o mais significativo (à esquerda), para representar o sinal. Quando este bit é 0, o número é positivo e, quando é 1, negativo. É importante sempre prestar atenção na quantidade de bits usada para representar o valor.
Representamos o valor decimal 5 em binário com 8 bits da seguinte forma.
00000101
Utilizando o primeiro bit para representar o sinal, temos então a seguinte representação para o valor -5.
10000101
Se estivéssemos usando 4 bits para representar o número, por exemplo, então teríamos 5 representado como 0101
e -5 como 1101
.
Vamor escrever toda a faixa de valores representáveis com 4 bits, incluindo números negativos.
-7: 1111
-6: 1110
-5: 1101
-4: 1100
-3: 1011
-2: 1010
-1: 1001
-0: 1000
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
Uma coisa estranha nessa representação é a presença de dois zeros: o zero negativo (1000) e o positivo (0000). Outra coisa estranha é quando tentamos somar valores positivos e negativos representados desta forma.
Ao somar 5 e -5, esperaríamos obter zero.
0101 (5)
+ 1101 (-5)
------
10010
Mas obtemos um número de 5 bits, apesar de estarmos trabalhando com 4 bits. Então ignoramos o primeiro 1, ficando somente com 0010
, que equivale a 2. Se você tentar somar outro valor positivo com um negativo, também não vai funcionar nesse sistema.
Então vamos ver outra forma de representação, chamada Complemento de 1, que resolve em partes os problemas dessa representação do sinal em 1 bit.
1.2. Complemento de 1
Na representação em complemento de 1, os números positivos continuam iguais, mas os bits dos valores negativos são trocados. Assim, enquanto 5 é 0101
, -5 é 1010
.
-7: 1000
-6: 1001
-5: 1010
-4: 1011
-3: 1100
-2: 1101
-1: 1110
-0: 1111
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
Vamos somar 5 e -5 mais uma vez e verificar o resultado.
0101 (5)
+ 1010 (-5)
------
1111 (-0)
Dessa forma, obtemos zero negativo (1111), que é mais próximo do valor correto do que o 2 obtido na soma que fizemos com os números representados usando o bit do sinal. Mas somar outros valores também funciona?
0111 (7)
+ 1101 (-2)
------
10100
Se ignorarmos o primeiro bit, uma vez que estamos trabalhando com 4 bits e não 5 bits, temos o valor decimal 4 (0100
). Mas 7 - 2 = 5 e não 4.
Vamos tentar com outro valor.
0101 (5)
+ 1110 (-1)
------
10011
Ignorando o primeiro bit, temos 5 - 1 = 3 (0011
). Incorreto mais uma vez, pois o correto seria 4.
Há um padrão interessante acontecendo. Os resultados obtidos na operação de soma de um valor positivo com um negativo representados em complemento de 1 é sempre o valor correto - 1. Ou seja, para obter o valor correto, pegamos o valor obtido e somamos 1 a ele.
- Para 7 - 2, obtemos 4. Logo, 4 + 1 = 5.
- Para 5 - 1, obtemos 3. Logo, 3 + 1 = 4.
- Para 5 - 5, obtemos -0. Logo, -0 + 1 = 0.
Espera, isso faz sentido? Nessa representação, sim. Veja:
1111 (-0)
+ 0001 (1)
------
10000
Obtemos 10000
. Ignoramos o primeiro bit e tudo bem, agora temos 0000
.
Outra forma de fazer isso é somar o último carry (que sempre vai ser 1) ao número de 4 bits obtido. Carry é o “vai 1” ou “vai 2”, etc, que temos quando estamos realizando uma soma no papel. Primeiro, somamos os números normalmente como já fizemos. Vamos testar com 5 e -1.
0101 (5)
+ 1110 (-1)
------
10011
^
Último carry
O último carry (1) é somado ao resultado considerando somente os 4 bits (0011
).
0011 (3)
+ 0001 (1)
------
0100
Assim, 3 + 1 = 4. Temos o resultado correto da operação 5 - 1.
Complemento de 1 parece uma boa abordagem para representar números negativos, uma vez que inverter bits em hardware é simples. Entretento, temos o problema que o valor sempre é uma unidade menor.
Vale a pena vermos uma abordagem que resolva esse problema, o Complemento de 2.
1.3. Complemento de 2
Usando complemento de 2, já nos livramos do zero negativo (e agora sobrou espaço para termos um -8, mas não para termos um 8).
-8: 1000
-7: 1001
-6: 1010
-5: 1011
-4: 1100
-3: 1101
-2: 1110
-1: 1111
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
Agora, se fizermos 5 + (-5), teremos:
0101 (5)
+ 1011 (-5)
------
10000
Ignoramos o primeiro bit e temos 0000
, ou zero. E se fizermos 5 - 1?
0101 (5)
+ 1111 (-1)
------
10100
Mais uma vez, ignoramos o primeiro bit e temos 0100
, ou 4. Mas, como obtemos o número negativo a partir do positivo? Como chegar de 6 (0110
) a -6 (1010
)?
É um processo de dois passos. Vamos observar esses passos com o número 6 (0110
).
- Inverta os bits do valor:
0110 -> 1001
- Adicione 1 ao valor obtido:
1001 + 1 = 1010
Esse é o processo para negar um valor: transformá-lo de positivo para negativo e vice-versa.
Assim, finalmente temos uma representação que resolve o problema de todas as outras: sem zero negativo e sem precisar adicionar um ao resultado da soma de um valor negativo e um positivo.