Inteiros, sinal e overflow
Bases de numeração, conversões, representação de inteiros e overflow em largura limitada.
O código 1011 vale 11 sem sinal e -5 em complemento para dois com quatro bits. Os bits mantêm-se; a interpretação muda os pesos. Antes de calcular, precisamos de conhecer a base, a representação e a largura.
Pesos posicionais
Na base , cada algarismo está entre 0 e e tem peso ; a vírgula separa os pesos inteiros dos fracionários, com
Por exemplo, soma os pesos :
O índice marca o algarismo das unidades, à esquerda da vírgula, enquanto marcam a parte fracionária; o subscrito 2 ou 10 indica a base e não faz parte do número.
O bit mais significativo, MSB, é o de maior peso; o LSB é o de menor peso da palavra. Um byte tem 8 bits. KiB significa bytes; kB significa bytes. Indica a unidade quando calculares capacidade.
Converter a parte inteira
Para converter 173 para binário, divide sucessivamente por 2 e guarda os restos. Cada linha mostra um quociente com o resto correspondente:
| Divisão | Quociente | Resto |
|---|---|---|
| 173 / 2 | 86 | 1 |
| 86 / 2 | 43 | 0 |
| 43 / 2 | 21 | 1 |
| 21 / 2 | 10 | 1 |
| 10 / 2 | 5 | 0 |
| 5 / 2 | 2 | 1 |
| 2 / 2 | 1 | 0 |
| 1 / 2 | 0 | 1 |
Lê os restos de baixo para cima: . O primeiro resto corresponde ao peso , por isso não pode ficar à esquerda; confirma com .
O método funciona para qualquer base inteira; para hexadecimal, , pelo que obtemos AD, usando A para 10 e D para 13.
Converter a parte fracionária
Multiplica a fração por 2; a parte inteira obtida é o próximo bit e continua-se com a parte fracionária, como em
Os bits lêem-se agora por ordem direta e são 101, logo ; para uma base , substitui a multiplicação por 2 por uma multiplicação por .
Uma fração reduzida tem expansão binária finita se o denominador for uma potência de 2. Por exemplo, termina; não termina porque o denominador contém um fator 5. Se parares após bits, truncaste a representação, e o valor guardado pode diferir do pretendido.
Agrupar bits
Como , cada algarismo hexadecimal corresponde a 4 bits, e como , cada algarismo octal corresponde a 3 bits. Agrupa a partir da vírgula para fora e acrescenta zeros apenas nas extremidades necessárias:
Em octal, . O zero acrescentado à esquerda não altera o inteiro, tal como o zero acrescentado à direita da fração não altera o seu valor.
Quantos bits são necessários
Com bits há códigos; o símbolo significa o menor inteiro maior ou igual a . Para distinguir situações precisamos de bits, por isso números de 0 até 300, com 301 valores, exigem 9 bits, pois 8 bits só dão 256 códigos.
Um hexadecimal de 32 bits tem 8 algarismos, porque . Não confundas o número de algarismos impressos com o número de bits: 0x0000000F ocupa 32 bits nesta escrita, mas o valor 15 cabe em 4 bits sem sinal.
Três representações
Uma palavra de bits tem padrões. O hardware pode somar esses padrões sem saber se os interpretamos com ou sem sinal. A interpretação determina o intervalo válido e a condição de overflow.
| Representação em bits | Intervalo | Zeros |
|---|---|---|
| Sem sinal | a | Um |
| Sinal e magnitude | a | Dois |
| Complemento para dois | a | Um |
Em sinal e magnitude, o MSB indica o sinal e os restantes bits dão o módulo. Em 8 bits, 10010110 representa , mas 10000000 é um zero negativo. Somar diretamente os códigos não implementa a adição dos valores com sinal.
Em complemento para dois, o MSB tem peso negativo, com
Assim 11101010 vale , que também se lê como o inteiro sem sinal 234 menos 256.
Negação e extensão
Para representar em 8 bits, escreve , inverte (11101001) e soma 1 (11101010); isto calcula .
O mínimo não tem simétrico positivo em 8 bits, pois inverter e somar 1 ao código 10000000 devolve o mesmo padrão e não produz um representável.
Ao aumentar a largura, números sem sinal recebem zeros à esquerda. Em complemento para dois, repete-se o bit de sinal: 11101010 passa a 11111111 11101010. Em sinal e magnitude, conserva-se o bit de sinal na nova posição e acrescentam-se zeros à magnitude. Não mistures estas regras.
Adição e subtração
A soma de palavras conserva os bits inferiores, ou seja, calcula módulo . A subtração usa .
Segue em 8 bits. A soma matemática é 140, código 10001100. Sem sinal, o resultado está certo. Em C2, esse código vale : 140 excede o máximo 127.
Segue agora . Os códigos somam 11111111 + 00000001 = 1 00000000. Há carry para fora, mas a palavra guardada 00000000 vale 0, que é o resultado certo em C2.
O par carry/overflow distingue os mundos: usa o carry final para sem sinal e para C2. Os três casos seguintes mostram as combinações sem mudar a largura a meio da conta:
| Soma em 4 bits | Soma completa dos códigos | Palavra guardada | Carry | Overflow C2 |
|---|---|---|---|---|
0 1000 | 1000, valor -8 | 0 | Sim: 8 excede 7 | |
1 0000 | 0000, valor 0 | 1 | Não | |
1 0111 | 0111, valor 7 | 1 | Sim: -9 é menor que -8 |
O carry pertence à soma dos códigos sem sinal. Para C2, compara o resultado matemático com o intervalo ou aplica as regras de sinais. O somador é o mesmo nos dois casos; a pergunta que fazes aos bits é que muda. Por isso, o mesmo padrão pode ser válido sem sinal e inválido com sinal, ou o inverso: carry e overflow com sinal variam de forma independente, e as quatro combinações são possíveis. Escreve a largura e a interpretação antes de avaliar qualquer soma.
| Operação | Overflow com sinal |
|---|---|
| Entradas com o mesmo sinal e resultado com sinal diferente | |
| Entradas com sinais diferentes e resultado com sinal diferente de |
Num somador, o overflow com sinal também é : compara o carry que entra no bit de sinal com o que sai. Para adição sem sinal, indica overflow. Na subtração por complemento, um carry final 1 indica que não foi necessário empréstimo.
Segue em 8 bits. A soma matemática é 140, que ultrapassa 127. O circuito soma 01100100 a 00101000 e guarda 10001100, lido como -116: os operandos tinham sinais diferentes e o resultado tem sinal diferente do primeiro. No outro sentido, guarda 01110100, lido como +116. A regra vale nos dois sentidos.
Multiplicação e comparação
O produto exato de dois números de bits pode precisar de bits. Para , os produtos parciais binários são os deslocamentos de 1101 correspondentes aos bits 1 de 1011: . Em 8 bits com sinal, 143 não cabe, embora caiba em 8 bits sem sinal.
Para multiplicar negativos sem perder o sinal, estende os operandos para a largura do resultado antes de construir os produtos, ou usa uma operação de multiplicação com sinal; conservar só os bits inferiores dá o mesmo padrão modular, mas perde a informação de que o produto completo não cabe.
Sem sinal, 11111111 é maior que 00000001. Com sinal, representa e é menor que 1. A comparação deve usar a interpretação do problema; ordenar códigos como inteiros sem sinal não ordena os negativos corretamente.
Escolher a largura
Para representar todos os valores de a 90, exige-se e . Com 7 bits, o máximo é 63, e com 8 é 127, por isso a largura mínima é 8.
Não decidas a largura só pelo módulo do valor mínimo. O intervalo assimétrico permite representar em 8 bits, mas não . Antes de uma conta, escreve o intervalo; depois compara o resultado matemático com esse intervalo.
Exercícios
Converter as duas partes
Converte para binário e hexadecimal, mostrando os pesos ou os passos.
Pista
Separa 45 de 0,375.
Mais uma pista
A fração é 3/8. Agrupa em quatro bits a partir da vírgula.
Solução
. . Portanto . Em grupos de quatro: , ou . O zero final da fração serve só para completar o grupo.
Confere a tua resposta:
- Binário 101101,011 e hexadecimal 2D,6.
- Mostra os pesos ou a conversão das duas partes.
Erros frequentes
Não leias os bits fracionários pela ordem inversa nem agrupes atravessando a vírgula.
Uma fração termina?
Quais das frações , e têm representação binária finita? Justifica.
Pista
Reduz cada fração antes de examinares o denominador.
Mais uma pista
6/24 reduz para 1/4; 40 contém o fator 5.
Solução
e terminam porque os denominadores reduzidos são potências de 2. não termina porque 40 tem fator 5 e a fração já está reduzida. Ser uma fração decimal finita não garante expansão binária finita.
Confere a tua resposta:
- 9/32 e 6/24 terminam; 7/40 não.
- Reduz 6/24 e identifica o fator 5 em 40.
Erros frequentes
Não examines o denominador sem simplificar a fração.
Codificar estados de um dispositivo
Precisamos de distinguir 513 mensagens, incluindo a mensagem vazia. Qual é a largura mínima do código?
Pista
Compara 513 com potências de 2.
Solução
e . Precisamos de 10 bits. A mensagem vazia já está incluída nas 513, por isso não se acrescenta mais um estado.
Erros frequentes
Não arredondes o logaritmo para baixo nem contes a mensagem vazia duas vezes.
Mesmo número, códigos diferentes
Representa -37 em 8 bits em sinal e magnitude e em complemento para dois. Descodifica ambos para confirmar.
Pista
A magnitude 37 é 0100101 em 7 bits.
Mais uma pista
Em C2 calcula 256−37.
Solução
Em sinal e magnitude: 1 0100101, ou 10100101. Em C2: , código 11011011. O primeiro separa sinal e magnitude 37; o segundo vale . Os padrões diferem porque as regras diferem.
Confere a tua resposta:
- Sinal e magnitude 10100101; C2 11011011.
- Descodifica os dois como -37 pelas respetivas regras.
Erros frequentes
Não interpretes o padrão de sinal e magnitude com os pesos de C2.
Duas interpretações da soma
Em 8 bits, soma primeiro 11110000 e 00110000, depois 01110000 e 00110000. Para cada soma indica a palavra guardada, o carry final e o overflow com sinal. Interpreta os resultados sem sinal e em complemento para dois.
Pista
Calcula primeiro a soma completa de 9 bits.
Mais uma pista
Sem sinal são 240 e 48; com sinal são -16 e 48.
Solução
A primeira soma completa é . A palavra final é 00100000, carry=1. Em C2, a soma é , que cabe; overflow com sinal=0. Sem sinal, 288 excede 255.
A segunda soma é . Não há carry final e o resultado sem sinal é válido. Em C2, 160 excede 127, e 10100000 representa -96: duas entradas positivas produziram um código negativo, logo overflow com sinal=1. Uma flag não substitui a outra.
Confere a tua resposta:
- Primeira soma: 00100000, carry 1 e overflow C2 0.
- Segunda soma: 10100000, carry 0 e overflow C2 1.
- Justifica cada flag pela interpretação e pelo intervalo.
Erros frequentes
Um carry 1 não prova overflow com sinal.
Produto exato e largura
Dois operandos de 8 bits com sinal valem -100 e 3. O produto cabe em 8 bits? Qual é a largura mínima para guardar o resultado exato?
Pista
Calcula -300 e compara com os intervalos C2.
Mais uma pista
9 bits chegam a -256; 10 bits chegam a -512.
Solução
O produto é -300, fora de [-128,127]. Nove bits ainda não chegam, pois o mínimo é -256. Dez bits dão [-512,511], logo a largura mínima do resultado é 10 bits. Uma multiplicação geral de dois operandos de 8 bits pode reservar 16 bits para cobrir todos os produtos.
Confere a tua resposta:
- Produto -300, que não cabe em oito nem em nove bits C2.
- Largura mínima dez bits; distingue-a de dezasseis bits para qualquer produto.
Erros frequentes
Distingue a largura mínima deste resultado da largura suficiente para qualquer par de operandos.
Alargar sem mudar o valor
O código de 8 bits 10000001 passa a 12 bits. Escreve a extensão correta para unsigned e para C2 e identifica os valores.
Pista
O preenchimento depende da interpretação.
Mais uma pista
Em C2, repete quatro vezes o bit de sinal.
Solução
Unsigned: 0000 10000001, valor 129. C2: 1111 10000001, valor -127. Acrescentar zeros a um C2 negativo mudaria o valor para +129, porque zeros à esquerda valem sempre potências positivas de 2. O padrão de origem é o mesmo; o contrato numérico é diferente.
Confere a tua resposta:
- Unsigned 000010000001 vale 129.
- C2 111110000001 vale -127.
Erros frequentes
Não apliques extensão de sinal a um valor declarado sem sinal.