Aula 1 — Sistemas de Representação da Informação
Apresentação
Tudo o que um computador armazena, transporta ou processa — um número, uma letra, um endereço de memória, uma instrução de máquina — é, fisicamente, uma sequência de bits. Um mesmo padrão de bits pode significar coisas completamente diferentes: 11111010 vale 250 se for lido como inteiro sem sinal, −6 se for lido em complemento de dois e ú se for lido como caractere Latin-1.
Esta aula trata justamente disso: quais convenções existem para dar significado a sequências de bits e quais são as consequências práticas de cada escolha.
Se você não cursou Fundamentos de Circuitos Digitais, comece pela Revisão de Fundamentos de Circuitos Digitais. As seções 1 e 2 desta aula retomam a conversão de bases e as funções lógicas com mais profundidade — o restante (caracteres, inteiros com sinal e ponto flutuante) é conteúdo novo.
Onde este conteúdo será usado na disciplina
| Seção desta aula | Onde aparece em Organização de Computadores |
|---|---|
| 1. Sistemas de numeração | Endereçamento de memória; codificação binária e hexadecimal de instruções |
| 2. Operações lógicas | Construção da ULA e da unidade de controle |
| 3. Operações aritméticas | ULA; deslocamentos como otimização de multiplicação e divisão |
| 4. Representação de caracteres | Dispositivos de E/S; dados armazenados em memória |
| 5. Números inteiros | Registradores, flags e aritmética com sinal na ULA |
| 6. Números fracionários | Unidades de ponto flutuante; limites de precisão |
| 7. Multiplicadores binários | Dimensionamento de memória e de barramentos |
Objetivos
Ao final desta aula você deve ser capaz de:
- Converter valores entre bases quaisquer, com atenção especial às bases 2, 8, 10 e 16, incluindo valores fracionários.
- Efetuar as quatro operações aritméticas em binário e explicar por que deslocamentos substituem multiplicações e divisões por potências de 2.
- Descrever as funções lógicas fundamentais (AND, OR, NOT, XOR, NAND, NOR, XNOR) por meio de tabelas-verdade.
- Comparar os padrões ASCII, ISO/IEC 8859-1 e Unicode, e codificar um texto em UTF-8.
- Representar números inteiros com sinal em BCD, sinal-magnitude, excesso-K, complemento a um e complemento a dois, e justificar por que o complemento a dois é a convenção universal nos processadores atuais.
- Construir e interpretar a representação de um número real no padrão IEEE-754 de precisão simples, e identificar as situações de perda de precisão, overflow e underflow.
1. Sistemas de Numeração
1.1 A origem dos números e a ideia de base
A necessidade de contar é anterior à escrita: cavernas pré-históricas registram contagens na forma de riscos agrupados por traços diagonais. Diversos povos inventaram formas próprias de contar. Aprendemos a contar nos dez dedos, e isso nos parece natural — mas os sumérios e babilônios contavam usando o polegar para apontar as três falanges dos outros quatro dedos, chegando a 12 por mão. Daí a persistência histórica do 12 e do 60 (5 mãos de 12) na divisão do dia em 24 horas e da hora em 60 minutos (IFRAH, 2009).
O número 60 é múltiplo de 2, 3, 4, 5 e 6, o que facilita divisões mentais — provavelmente o motivo de sua sobrevivência até hoje.
A notação romana usava símbolos de valores distintos (I, V, X, L, C), de modo semelhante às nossas cédulas de 2, 5, 10, 20, 50 e 100 reais: representar 60 como LX é preferível a XXXXXX, assim como preferimos uma nota de 50 e outra de 10 a seis notas de 10. Nessa notação não havia representação do zero — dizer "zero notas de 10" era informação inócua.
A invenção decisiva veio com os hindus, por volta do século V: a notação posicional, em que apenas a quantidade de "notas" de cada tipo é escrita, e o valor de cada tipo é dado pela posição do dígito. Foi essa notação que tornou o zero indispensável — ele passou a marcar a ausência de uma casa. O valor fundamental que define as casas (1, 10, 100, 1000...) é a base do sistema.
1.2 O odômetro como analogia
Um odômetro mecânico ajuda a entender qualquer base: cada rodinha gira e, ao ultrapassar seu maior dígito, incrementa a rodinha à esquerda. O odômetro comum tem dez dígitos por rodinha (0 a 9) porque nosso sistema é decimal — mas isso é convenção histórica, não necessidade. Um odômetro babilônico teria 12 dígitos por rodinha (usando, por exemplo, A e B como símbolos extras):
| Decimal | Odômetro duodecimal |
|---|---|
| 9 | 000009 |
| 10 | 00000A |
| 11 | 00000B |
| 12 | 000010 |
| 13 | 000011 |
Esse sistema hipotético seria o duodecimal (base 12).
Notação. Ao trabalhar fora da base 10, indicamos a base em subscrito, opcionalmente entre parênteses: 1B15A2₍₁₂₎ lê-se "na base 12".
Por volta de 1717, o rei Carlos XII da Suécia defendia que seria mais eficiente calcular usando apenas os dígitos de 0 a 7 — o sistema octal. Morreu em batalha antes de implantar a ideia, que ressurgiu cerca de 250 anos depois em linguagens de programação como C.
1.3 Representação posicional
Em um sistema posicional de base b, cada dígito é multiplicado por uma potência de b determinada por sua posição:
No sistema decimal:
372 = 3 × 10² + 7 × 10¹ + 2 × 10⁰ = 300 + 70 + 2
A contagem funciona sempre do mesmo modo: cada casa começa em 0 e, ao esgotar seus dígitos, incrementa a casa à esquerda. Em base 5 existem apenas os dígitos 0, 1, 2, 3 e 4 (não existe o dígito "5"), e a contagem é: 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21… Por isso 13₍₅₎ = 8₍₁₀₎.
1.4 Representação binária
Os primeiros computadores eletromecânicos, como o Mark I, trabalhavam em base 10. Os circuitos, porém, eram complexos: cada dígito exigia dez representações distintas. A solução foi adotar apenas dois dígitos, 0 e 1 — a base 2.
A razão é elétrica, não matemática: é muito mais simples e confiável associar "0" a um circuito desligado e "1" a um circuito ligado do que distinguir dez níveis diferentes de tensão. A contagem em base 2 é:
000 001 010 011 100 101 110 111 ...
0 1 2 3 4 5 6 7
O preço é o tamanho da representação: 1111111111₍₂₎ = 1023₍₁₀₎ — dez dígitos binários para três decimais. A simplicidade e a confiabilidade do circuito compensam largamente.
1.5 Octal e hexadecimal
Escrever longas sequências de bits é uma fonte constante de erro de transcrição. Por isso usamos duas bases cuja conversão para binário é imediata: a octal (base 8), hoje em desuso, e a hexadecimal (base 16), amplamente usada.
Octal — dígitos de 0 a 7. Depois de 77 vem 100.
Hexadecimal — 16 símbolos: 0 a 9 e A a F.
| Hex | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| Decimal | 10 | 11 | 12 | 13 | 14 | 15 |
A contagem segue: …, E, F, 10, 11, …, 1F, 20, …, FF, 100, 101…
1.6 Conversão entre bases
De uma base qualquer para a base 10 — soma ponderada:
142₍₈₎ = 1×8² + 4×8¹ + 2×8⁰ = 64 + 32 + 2 = 98₍₁₀₎
1001₍₂₎ = 1×2³ + 0×2² + 0×2¹ + 1×2⁰ = 8 + 1 = 9₍₁₀₎
1C7A₍₁₆₎ = 1×16³ + 12×16² + 7×16¹ + 10×16⁰ = 4.096 + 3.072 + 112 + 10 = 7.290₍₁₀₎
Qualquer número elevado a zero vale 1, não 0. O dígito da casa mais à direita é sempre multiplicado por b⁰ = 1.
Da base 10 para uma base B — divisões sucessivas por B até o quociente ser zero; a resposta é a sequência de restos lida de baixo para cima.
Exemplo 1.1 — Converter 103₍₁₀₎ para base 5.
| Divisão | Quociente | Resto |
|---|---|---|
| 103 ÷ 5 | 20 | 3 |
| 20 ÷ 5 | 4 | 0 |
| 4 ÷ 5 | 0 | 4 |
Lendo de baixo para cima: 103₍₁₀₎ = 403₍₅₎. Verificação: 4×25 + 0×5 + 3 = 103 ✔
Exemplo 1.2 — Converter 300₍₁₀₎ para hexadecimal.
| Divisão | Quociente | Resto |
|---|---|---|
| 300 ÷ 16 | 18 | 12 → C |
| 18 ÷ 16 | 1 | 2 |
| 1 ÷ 16 | 0 | 1 |
Logo, 300₍₁₀₎ = 12C₍₁₆₎.
Entre binário e bases potência de 2 — a conversão é direta por agrupamento, sem passar pelo decimal: 3 bits por dígito octal (8 = 2³) e 4 bits por dígito hexadecimal (16 = 2⁴), agrupando a partir da direita.
| Base 8 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| Base 2 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
| Hex | Bin | Hex | Bin |
|---|---|---|---|
| 0 | 0000 | 8 | 1000 |
| 1 | 0001 | 9 | 1001 |
| 2 | 0010 | A | 1010 |
| 3 | 0011 | B | 1011 |
| 4 | 0100 | C | 1100 |
| 5 | 0101 | D | 1101 |
| 6 | 0110 | E | 1110 |
| 7 | 0111 | F | 1111 |
416₍₈₎ = 100 001 110₍₂₎
3CF1₍₁₆₎ = 0011 1100 1111 0001₍₂₎
Para montar a tabela hexadecimal de cabeça, memorize apenas a tabela octal (3 bits) e escreva-a duas vezes lado a lado, prefixando a primeira metade com 0 e a segunda com 1.
Entre duas bases quaisquer — converta primeiro para a base 10 e, em seguida, para a base de destino.
Exemplo 1.3 — Converter 317₍₈₎ para base 5.
1) 317₍₈₎ = 3×64 + 1×8 + 7 = 207₍₁₀₎
2) 207 ÷ 5 = 41, resto 2
41 ÷ 5 = 8, resto 1
8 ÷ 5 = 1, resto 3
1 ÷ 5 = 0, resto 1
3) 317₍₈₎ = 207₍₁₀₎ = 1312₍₅₎
1.7 Resumo da seção 1
- Em um sistema posicional, o valor de um dígito depende da sua posição; a base define o peso de cada casa.
- O binário é adotado por razões de implementação física, não matemáticas.
- Octal e hexadecimal são notações compactas para o binário, com conversão imediata por agrupamento de 3 e 4 bits.
- Base qualquer → base 10: soma ponderada. Base 10 → base B: divisões sucessivas, restos lidos de trás para frente.
2. Operações Lógicas
2.1 A álgebra de Boole
No cotidiano agimos a partir de condições: "somente se alguém me procurar, me acorde" — uma ação condicionada a uma premissa verdadeira. O matemático George Boole formalizou esse tipo de raciocínio como equações sobre variáveis que assumem apenas dois valores, em A Análise Matemática da Lógica (1847) e As Leis do Pensamento (1854). Por convenção, 0 representa o que não acontece e 1 o que acontece. Sobre essa base — a álgebra de Boole — se constroem todos os circuitos digitais.
Um exemplo: sendo d = "eu me dedico", r = "a prova é razoável" e p = "eu passo":
d AND r = p
Com b = "a prova é brutalmente difícil", a mesma ideia fica:
d AND (NOT b) = p
2.2 Operadores fundamentais
NOT — unário; inverte o valor.
| x | NOT x |
|---|---|
| 0 | 1 |
| 1 | 0 |
AND — resultado 1 apenas quando ambas as entradas são 1.
| x | y | x AND y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
OR — resultado 1 quando pelo menos uma entrada é 1.
| x | y | x OR y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
2.3 Funções derivadas
| x | y | XOR | NAND | NOR | XNOR |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 1 | 1 |
| 0 | 1 | 1 | 1 | 0 | 0 |
| 1 | 0 | 1 | 1 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 1 |
- XOR ("ou exclusivo") vale 1 quando as entradas são diferentes.
- NAND é o AND com a saída negada; NOR, o OR com a saída negada; XNOR, o XOR com a saída negada.
A soma binária de 1 bit, desconsiderando o "vai um", é exatamente a função XOR. Esse é o núcleo do meio somador e, por extensão, da ULA — assunto que retorna na seção 3 e na unidade de CPU.
2.4 Resumo da seção 2
- A álgebra de Boole opera sobre dois valores (0 e 1) com três primitivas: AND, OR e NOT.
- XOR, NAND, NOR e XNOR são combinações das primitivas, mas são implementadas diretamente em hardware por economia de circuito.
- XOR é o bit de soma; AND é o bit de "vai um" — os dois formam o meio somador.
3. Operações Aritméticas
Os algoritmos manuais de soma, subtração, multiplicação e divisão em binário são idênticos aos do decimal. O que muda é apenas a tabuada.
3.1 Adição
Tabuada: 0+0=0; 0+1=1; 1+0=1; 1+1=0 e vai 1 (porque 1+1 = 10₍₂₎ = 2₍₁₀₎).
Exemplo 3.1 — 01₍₂₎ + 11₍₂₎:
0 1
+ 1 1
------
1 0 0
Da direita para a esquerda: 1+1 = 0 com "vai 1"; depois 0+1+1 = 0 com "vai 1"; resultado 100₍₂₎ = 4.
3.2 Subtração
Tabuada: 0−0=0; 0−1=1 e empresta; 1−0=1; 1−1=0. Exemplo: 100₍₂₎ − 011₍₂₎ = 001₍₂₎.
3.3 Multiplicação
Tabuada: 0×0=0; 0×1=0; 1×0=0; 1×1=1. O algoritmo é o mesmo das parcelas deslocadas do decimal — por exemplo, 1010₍₂₎ × 1101₍₂₎ (10 × 13). A atenção redobrada fica por conta dos "vai um" na soma das parcelas.
3.4 Divisão
Também idêntica à divisão decimal: compara-se o início do dividendo com o divisor; se for maior ou igual, escreve-se 1 no quociente, multiplica-se e subtrai-se; repete-se até o fim do dividendo, e o que sobra é o resto. Exemplo: 11011₍₂₎ ÷ 11₍₂₎ (27 ÷ 3).
3.5 Multiplicação e divisão por potências de 2
Em decimal, multiplicar por 10ⁿ equivale a acrescentar n zeros à direita. Em binário, multiplicar por 2ⁿ equivale a acrescentar n zeros à direita:
2.476 × 10³ = 2.476.000 (decimal)
10011011₍₂₎ × 10₍₂₎ = 100110110₍₂₎ (155 × 2 = 310)
Essa operação tem nome próprio em hardware: deslocamento à esquerda (shift left, <<), muito mais rápida que a multiplicação genérica. Por isso é comum decompor multiplicações em somas de deslocamentos:
K × 9 = (K × 8) + (K × 1) = (K << 3) + K
Simetricamente, dividir por 2ⁿ equivale a remover n dígitos à direita (que formam o resto) — o deslocamento à direita (shift right, >>):
2.476.235 ÷ 100 = 24.762 (resto 35) (decimal)
1001101101₍₂₎ ÷ 10000₍₂₎ = 100110₍₂₎ (resto 1101₍₂₎) (÷ 16)
30.342 ÷ 16 = 30.342 >> 4 = 1.896
Compiladores reconhecem multiplicações e divisões por potências de 2 e as substituem por deslocamentos. É uma das otimizações mais antigas e baratas que existem — e um bom exemplo de como a organização do hardware influencia o software.
3.6 Valores fracionários
Deslocar a vírgula também funciona em binário:
1001101101,₍₂₎ ÷ 10000₍₂₎ = 100110,1101₍₂₎
Fracionário binário → decimal — mesma soma ponderada, agora com expoentes negativos:
100110,1101₍₂₎ = 32 + 4 + 2 + 0,5 + 0,25 + 0,0625 = 38,8125₍₁₀₎
Fracionário decimal → binário — multiplicações sucessivas da parte fracionária por 2, concatenando as partes inteiras obtidas:
0,75 × 2 = 1,50 → 1
0,50 × 2 = 1,00 → 1
0,75₍₁₀₎ = 0,11₍₂₎
A parte inteira é convertida à parte, pelas divisões sucessivas: 132,75₍₁₀₎ = 10000100,11₍₂₎.
Frações decimais aparentemente triviais — 0,1; 0,2; 0,3; 0,4; 0,6; 0,8; 0,9 — geram dízimas periódicas em binário e precisam ser truncadas. É daí que vêm os erros de arredondamento em ponto flutuante (o clássico 0.1 + 0.2 != 0.3). O problema é inerente à representação posicional com número finito de dígitos, não uma falha do binário.
3.7 Resumo da seção 3
- Os algoritmos aritméticos binários são os mesmos do decimal, com tabuadas menores.
<< nmultiplica por2ⁿ;>> ndivide por2ⁿ(o que sai à direita é o resto).- Conversão de fracionários: para decimal, soma ponderada com expoentes negativos; para binário, multiplicações sucessivas por 2.
- Nem todo fracionário decimal tem representação binária finita.
4. Representação de Caracteres
4.1 ASCII
A representação de caracteres começou modesta: os dígitos 0–9, as 26 letras do alfabeto inglês em duas caixas e alguns símbolos e caracteres de controle — 128 símbolos ao todo, o que exige 7 bits. Esse é o padrão ASCII (American Standard Code for Information Interchange).
Trecho da tabela (código hexadecimal = coluna × 0x10 + linha):
| 0x2_ | 0x3_ | 0x4_ | 0x5_ | 0x6_ | 0x7_ | |
|---|---|---|---|---|---|---|
| 0 | SP | 0 | @ | P | ` | p |
| 1 | ! | 1 | A | Q | a | q |
| 2 | " | 2 | B | R | b | r |
| 3 | # | 3 | C | S | c | s |
| 9 | ) | 9 | I | Y | i | y |
| A | * | : | J | Z | j | z |
| F | / | ? | O | _ | o | DEL |
Assim, A está na coluna 4, linha 1 → 0x41; a → 0x61; 0 → 0x30.
Os 32 primeiros códigos (0x00–0x1F) são caracteres de controle, herdados dos teletipos: NUL (nulo), SOH (início de cabeçalho), STX/ETX (início/fim de texto), EOT (fim de transmissão), ACK/NAK (confirmação positiva/negativa), BEL (campainha), BS (backspace), HT (tabulação horizontal), LF (nova linha), VT (tabulação vertical), FF (nova página), CR (retorno de carro), ESC (escape) e DEL (apagar). Muitos perderam o propósito original — o FF, que avançava o papel da impressora, hoje limpa a tela em vários terminais.
O ASCII não prevê caracteres acentuados, mas é extremamente portátil.
4.2 ISO/IEC 8859-1 (Latin-1)
A extensão natural foi usar os 8 bits do byte, dobrando a tabela para 256 caracteres. Como não cabia tudo em uma única tabela, o padrão ISO/IEC 8859 foi dividido em partes; a mais usada é a ISO/IEC 8859-1 (Latin-1), voltada às línguas da Europa Ocidental e da América Latina.
- Os primeiros 128 códigos são idênticos ao ASCII.
- Os 128 seguintes (0x80–0xFF) trazem acentuadas e símbolos:
À Á Â Ã Ä Ç È É Ê Í Ñ Ó Ô Õ Ú Ü ße suas minúsculas.
O padrão não cobre alfabetos não latinos (grego, cirílico, hebraico, árabe) — tratados em outras partes da norma — nem as escritas ideográficas do Leste Asiático, que exigem milhares de pontos de código.
4.3 Unicode
O Unicode, mantido pelo Unicode Consortium, permite codificar textos de praticamente todos os sistemas de escrita do mundo de forma consistente. Na versão 13.0 (março de 2020) continha 143.859 caracteres, cobrindo 154 sistemas de escrita modernos e históricos, além de símbolos e emojis. É mantido em sincronia com a norma ISO/IEC 10646 (UCS).
Um caractere Unicode é identificado por "U+" seguido do código em hexadecimal, no intervalo de U+0000 a U+10FFFF — um espaço de 21 bits.
O Unicode define pontos de código, não a forma de armazená-los. Isso fica a cargo dos formatos de transformação (UTF):
| UTF-8 | UTF-16 | UTF-32 | |
|---|---|---|---|
| Menor ponto de código | 0000 | 0000 | 0000 |
| Maior ponto de código | 10FFFF | 10FFFF | 10FFFF |
| Unidade de código | 8 bits | 16 bits | 32 bits |
| Mínimo de bytes por caractere | 1 | 2 | 4 |
| Máximo de bytes por caractere | 4 | 4 | 4 |
- UTF-8 — o mais usado na internet. Usa 1 byte para os 128 primeiros pontos de código (idênticos ao ASCII, o que torna todo texto ASCII um texto UTF-8 válido) e até 4 bytes para os demais.
- UTF-16 — 2 bytes para os 65.536 primeiros pontos de código (o Plano Multilíngue Básico, BMP) e 4 bytes para os demais. É o padrão interno do Windows, do Java (desde a versão 1.5) e do .NET.
- UTF-32 (UCS-4) — 4 bytes fixos por caractere: indexação trivial, mas consumo de espaço proibitivo. Pouco usado.
4.4 UTF-8 em detalhes
O UTF-8 foi criado em 1992 por Kenneth Thompson e Robert Pike, os criadores do UNIX, sob duas premissas: mensagens contendo apenas caracteres ASCII devem manter exatamente o mesmo código de 8 bits; e pontos de código fora do ASCII são transformados em sequências de 2, 3 ou 4 bytes.
| Intervalo do ponto de código | Sequência UTF-8 | Bits úteis |
|---|---|---|
| U+0000 – U+007F | 0xxxxxxx | 7 |
| U+0080 – U+07FF | 110xxxxx 10xxxxxx | 11 |
| U+0800 – U+FFFF | 1110xxxx 10xxxxxx 10xxxxxx | 16 |
| U+10000 – U+10FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 21 |
Exemplo 4.1 — Codificar a palavra "ações" em UTF-8.
| Caractere | Unicode | Binário do ponto de código | UTF-8 (binário) | UTF-8 (hex) |
|---|---|---|---|---|
| a | U+0061 | 0110 0001 | 01100001 | 61 |
| ç | U+00E7 | 1110 0111 | 11000011 10100111 | C3 A7 |
| õ | U+00F5 | 1111 0101 | 11000011 10110101 | C3 B5 |
| e | U+0065 | 0110 0101 | 01100101 | 65 |
| s | U+0073 | 0111 0011 | 01110011 | 73 |
A palavra ocupava 5 bytes em Latin-1 e passa a ocupar 7 bytes em UTF-8. Para um texto de 100 letras com 8 acentuadas, UTF-16 usaria 200 bytes, UTF-32 usaria 400 bytes e o UTF-8 apenas 92 + 2×8 = 108 bytes — o que explica seu domínio na web.
O UCS (Universal Coded Character Set, ISO/IEC 10646) é a base de muitas codificações, mantido em sincronia com o Unicode. O GB18030 é o padrão do governo chinês, obrigatório para softwares comercializados na China desde 2006; cobre chinês simplificado e tradicional além de mongol, uigur, tibetano e yi.
4.5 Resumo da seção 4
- ASCII: 7 bits, 128 caracteres, sem acentuação, altamente portátil.
- ISO/IEC 8859-1: 8 bits, superconjunto do ASCII, cobre o alfabeto latino ocidental.
- Unicode: repertório universal de pontos de código (U+0000 a U+10FFFF), independente da forma de armazenamento.
- UTF-8, UTF-16 e UTF-32 são formas de codificar os pontos de código em bytes; UTF-8 é compatível com ASCII e o mais econômico para textos latinos.
5. Representação de Números Inteiros
5.1 BCD (Binary Coded Decimal)
No BCD, cada dígito decimal é codificado separadamente em 4 bits (por isso também chamado BCD 8-4-2-1, pelos pesos dos bits):
| Decimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| BCD | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
Assim, 1965₍₁₀₎ vira 0001 1001 0110 0101. Quando dois dígitos são agrupados em um byte, fala-se em BCD compactado. As combinações sem dígito correspondente (1010 a 1111) às vezes indicam sinal (1100 positivo, 1101 negativo).
Desvantagens: desperdiça 6 das 16 combinações de cada grupo de 4 bits e complica a aritmética. Por isso foi rapidamente abandonado como representação numérica de uso geral.
O chip de relógio MC6818, dos PCs antigos, guardava data e hora em BCD, o que facilitava a conversão para ASCII. Os modelos antigos do PlayStation 3 faziam o mesmo — e em 1º de março de 2010 os consoles falharam mundialmente: o valor BCD 10 foi interpretado como hexadecimal 0x10 (16 em decimal), corrompendo funções do sistema.
5.2 Sinal-magnitude
O bit mais significativo indica o sinal (0 positivo, 1 negativo) e os demais representam a magnitude:
+6 → 00000110 −6 → 10000110
+100 → 01100100 −100 → 11100100
Faixa com n bits: de −(2ⁿ⁻¹ − 1) a +(2ⁿ⁻¹ − 1). Com 8 bits, de −127 a +127; com 16 bits, de −32.767 a +32.767.
Foi usada em computadores antigos (IBM 704/709/7090/7094). Está em desuso por dois motivos: exige lógica complexa para somar operandos de sinais diferentes e possui duas representações do zero (00000000 e 10000000).
5.3 Excesso-K
Também chamada excesso-N, deslocamento binário ou representação polarizada: subtrai-se um valor fixo K da representação binária para obter o valor real. A vantagem é que a sequência do valor mais negativo ao mais positivo é uma progressão binária simples — conveniente para contadores e comparações.
- Com
K = 2ⁿ⁻¹, o valor mínimo é representado por todos os bits em 0, o zero por1000…0e o máximo por todos os bits em 1. Nesse caso, converter para complemento a dois consiste apenas em inverter o bit mais significativo. - Com
K = 2ⁿ⁻¹ − 1(para n = 8, K = 127) tem-se a forma usada para o expoente no padrão IEEE-754, tratada na seção 6.
5.4 Complemento a um
Positivos têm bit mais significativo 0; negativos são obtidos invertendo todos os bits do positivo correspondente:
+6 → 00000110 −6 → 11111001
+100 → 01100100 −100 → 10011011
Faixa: de −(2ⁿ⁻¹ − 1) a +(2ⁿ⁻¹ − 1). A soma exige um passo extra, o end-around carry: soma-se normalmente e, se houver bit excedente, ele é somado de volta ao resultado. Foi usada no UNIVAC 1101, CDC 160/6600, LINC e PDP-1, mas também sofre da dupla representação do zero (00000000 e 11111111).
5.5 Complemento a dois
Positivos têm bit mais significativo 0; negativos são obtidos invertendo todos os bits e somando 1:
+6 → 00000110 −6 → 11111010
+100 → 01100100 −100 → 10011100
Faixa com n bits: de −2ⁿ⁻¹ a +(2ⁿ⁻¹ − 1) — com 8 bits, de −128 a +127; com 16 bits, de −32.768 a +32.767; com 32 bits, de −2.147.483.648 a +2.147.483.647. A assimetria vem de haver uma única representação do zero, o que libera um padrão a mais para o lado negativo.
Soma — soma-se normalmente em base 2; se o resultado exceder n bits, descarta-se o bit excedente:
00001010 (10) 01001010 ( 74)
+ 00000101 ( 5) + 11011010 (−38)
-------- ---------
00001111 (15) 1 00100100 (36) → descarta o bit extra
Subtração — calcula-se o complemento a dois do subtraendo e soma-se:
1011₍₂₎ − 0101₍₂₎
complemento a 2 de 0101 → 1010 + 1 = 1011
1011 + 1011 = 1 0110 → descartando o bit extra: 0110 (6)
Uma única representação do zero e, sobretudo, o mesmo circuito somador serve para somar e subtrair, com ou sem sinal, sem tratamento especial do bit de sinal. É por isso que praticamente todos os processadores comerciais atuais o adotam — e por isso a ULA que estudaremos adiante é construída em torno de um somador.
5.6 Resumo da seção 5
| Representação | Zero duplo? | Faixa (n bits) | Situação atual |
|---|---|---|---|
| BCD | — | 1 dígito por 4 bits | Nichos (relógios, displays) |
| Sinal-magnitude | Sim | −(2ⁿ⁻¹−1) a +(2ⁿ⁻¹−1) | Em desuso |
| Excesso-K | Não | depende de K | Expoente do IEEE-754 |
| Complemento a um | Sim | −(2ⁿ⁻¹−1) a +(2ⁿ⁻¹−1) | Em desuso |
| Complemento a dois | Não | −2ⁿ⁻¹ a +(2ⁿ⁻¹−1) | Padrão universal |
6. Representação de Números Fracionários
Ao armazenar números com parte fracionária é preciso decidir a priori quantos bits usar e como tratar a posição da vírgula. Há duas soluções consagradas: ponto fixo e ponto flutuante.
6.1 Ponto fixo
Reserva-se um total de n bits, dos quais f ficam com a parte fracionária e n − f com a parte inteira — divisão arbitrada pelo programador. Por exemplo, 11011,01₍₂₎ = 27,25₍₁₀₎ em 32 bits com 12 bits fracionários:
00000000000000011011 010000000000
20 bits (inteira) 12 bits (fracionária)
Vantagem: simplicidade. Soma e subtração são idênticas às de inteiros, desde que ambos os operandos usem o mesmo número de bits fracionários. Um inteiro binário é apenas um caso particular de ponto fixo, com f = 0 — inclusive quanto ao uso de complemento a dois para negativos.
Limitações: com n bits há apenas 2ⁿ valores representáveis, então muitos fracionários precisam ser truncados; e a escolha de f exige conhecer de antemão a faixa de valores a tratar, o que dificulta lidar com magnitudes muito diferentes na mesma aplicação.
O ponto fixo continua muito usado em processadores de sinais digitais (DSP) de baixo custo, que frequentemente não implementam ponto flutuante em hardware.
6.2 Ponto flutuante e o padrão IEEE-754
A notação científica resolve o problema das magnitudes: um quatrilhão é 1,0 × 10¹⁵. Como a mesma quantidade admite várias escritas (1,0 × 10¹⁵, 0,01 × 10¹⁷, 100,0 × 10¹³), adota-se uma forma normalizada. A forma geral é:
onde s é o sinal, m a mantissa, b a base e e o expoente. Nos computadores atuais, b = 2.
O padrão IEEE-754 define os formatos:
| Precisão | Sinal | Expoente | Mantissa | Total | Excesso do expoente | Dígitos decimais |
|---|---|---|---|---|---|---|
| Meia | 1 | 5 | 10 | 16 bits | 15 | ~3 |
| Simples | 1 | 8 | 23 | 32 bits | 127 | ~7 |
| Dupla | 1 | 11 | 52 | 64 bits | 1023 | ~15 |
| Quádrupla | 1 | 15 | 112 | 128 bits | 16383 | ~34 |
Três decisões de projeto merecem destaque:
- Sinal — 0 para positivo, 1 para negativo (bit isolado, não é complemento a dois).
- Expoente polarizado (excesso-K) — soma-se 127 (simples), 1023 (dupla) ou 16383 (quádrupla). Isso permite comparar expoentes como inteiros sem sinal. A faixa real vai de −126 a +127 na precisão simples.
- Bit implícito — a mantissa normalizada fica sempre entre 1 e 2, ou seja, começa por "1,". Como esse 1 é sempre igual, ele não é armazenado, e ganha-se 1 bit de precisão de graça.
Exemplo 6.1 — Representar −9,5 em precisão simples.
| Passo | Resultado |
|---|---|
| 1. Bit de sinal (negativo) | 1 |
| 2. Converter 9,5 para binário | 1001,1 |
| 3. Normalizar entre 1 e 2 | 1,0011 × 2³ |
| 4. Polarizar o expoente | 3 + 127 = 130 |
| 5. Expoente em binário | 10000010 |
| 6. Descartar o "1," implícito | mantissa = 0011 |
| 7. Completar 23 bits | 00110000000000000000000 |
s | expoente | mantissa
1 | 10000010 | 00110000000000000000000
Para o caminho inverso, basta desfazer os passos: separar os três campos, subtrair o excesso do expoente, recompor o bit implícito, desnormalizar e aplicar o sinal.
Valores especiais:
| Valor | Sinal | Expoente | Mantissa |
|---|---|---|---|
| Zero | 0 | 000…0 | 0 |
| +Infinito | 0 | 111…1 | 0 |
| −Infinito | 1 | 111…1 | 0 |
| NaN (Not a Number) | 0 | 111…1 | diferente de 0 |
O NaN representa exceções como divisão por zero ou raiz de número negativo. Nas comparações: +0 e −0 são iguais; qualquer NaN é diferente de qualquer valor, inclusive de si mesmo; e valores finitos são sempre menores que +∞ e maiores que −∞.
6.3 Aritmética em ponto flutuante
Soma e subtração, em três etapas:
- Equalizar os expoentes — o operando de menor expoente tem a mantissa deslocada à direita (dividida por 2 a cada incremento). Se os expoentes forem muito diferentes, há perda de precisão já nesta etapa.
- Somar ou subtrair as mantissas, com ajuste posterior de sinal.
- Normalizar o resultado — se a mantissa ficar maior ou igual a 2, desloca-se um bit à direita e incrementa-se o expoente; se ficar menor que 1, desloca-se à esquerda e decrementa-se o expoente.
Multiplicação e divisão são mais simples: somam-se (multiplicação) ou subtraem-se (divisão) os expoentes, com ajuste da constante de polarização; multiplicam-se ou dividem-se as mantissas; normaliza-se o resultado. O sinal é positivo quando os sinais dos operandos são iguais.
Underflow e overflow — pelo IEEE-754, ocorre underflow quando o expoente polarizado do resultado é menor que 1, e overflow quando é maior que 254 (simples), 2046 (dupla) ou 32766 (quádrupla).
6.4 Resumo da seção 6
- Ponto fixo: rápido e simples, mas exige conhecer a faixa dos dados de antemão.
- Ponto flutuante: faixa muito maior, ao custo de circuitos mais complexos e de precisão variável.
- No IEEE-754, o expoente é polarizado (excesso-K) e o bit mais significativo da mantissa é implícito.
- Perda de precisão em ponto flutuante não é defeito de implementação: é consequência de representar infinitos valores reais com um número finito de bits.
7. Multiplicadores Binários
O bit é a unidade fundamental de informação, implementada em hardware como dois níveis de tensão. O byte (ou octeto) é o conjunto de 8 bits — a menor unidade endereçável individualmente. Atenção à abreviação: "b" minúsculo é bit, "B" maiúsculo é byte.
Historicamente, os prefixos decimais do SI (k = 10³, M = 10⁶, G = 10⁹) passaram a ser usados também para potências de 2 (1.024, 1.048.576, …), sobretudo ao descrever memória. A ambiguidade gerava confusão: um HD anunciado com 1.000 GB (1 TB decimal) aparece no sistema operacional com cerca de 931 GiB.
Em 2008, a norma IEC 80000-13 padronizou os prefixos binários:
| Decimal (SI) | Binário (IEC) | Valor |
|---|---|---|
| k (quilo) | Ki (kibi) | 2¹⁰ |
| M (mega) | Mi (mebi) | 2²⁰ |
| G (giga) | Gi (gibi) | 2³⁰ |
| T (tera) | Ti (tebi) | 2⁴⁰ |
| P (peta) | Pi (pebi) | 2⁵⁰ |
| E (exa) | Ei (exbi) | 2⁶⁰ |
| Z (zeta) | Zi (zebi) | 2⁷⁰ |
| Y (yota) | Yi (yobi) | 2⁸⁰ |
Convenção usual: prefixos binários (KiB, MiB, GiB) para capacidade de armazenamento e memória; prefixos decimais (kbps, Mbps, MB/s) para taxas de transmissão.
Exercícios
Os exercícios abaixo cobrem as sete seções desta aula. Tente resolver cada um antes de revelar o gabarito.
Seção 1 — Sistemas de numeração
Converta 173₁₀ para binário, octal e hexadecimal.
Converta 2F5₁₆ para binário e para decimal.
Converta 214₁₀ para base 5, mostrando as divisões sucessivas, e verifique o resultado.
Por que o hexadecimal é preferido ao decimal para escrever endereços de memória e códigos de instrução, se o computador não trabalha em base 16?
Seção 2 — Operações lógicas
Construa a tabela-verdade da expressão d AND (NOT b) e interprete o resultado no contexto do exemplo desta aula (d = 'me dediquei', b = 'a prova foi brutalmente difícil', resultado = 'passei').
Mostre que a coluna de soma (sem o 'vai um') da adição binária de 1 bit é idêntica à tabela-verdade do XOR, e que o 'vai um' corresponde ao AND.
Seção 3 — Operações aritméticas
Efetue a soma 10110₂ + 1101₂ em binário e confira o resultado em decimal.
Reescreva a multiplicação K × 20 como uma soma de deslocamentos. Por que um compilador faria essa substituição?
Converta 0,375₁₀ para binário pelo método das multiplicações sucessivas e depois converta 101,101₂ para decimal.
Por que 0,1₁₀ não tem representação binária exata, e que consequência prática isso tem em um programa?
Seção 4 — Caracteres
Escreva a palavra 'Bit' em ASCII, apresentando cada caractere em hexadecimal e em binário de 8 bits.
Codifique a palavra 'só' em UTF-8, apresentando o resultado em binário e em hexadecimal.
Quantos bytes ocupa a palavra 'Atenção' em UTF-8? E em UTF-16 e UTF-32?
Qual foi a motivação para criar o Unicode, se o ISO/IEC 8859-1 já cobria as línguas latinas?
Seção 5 — Números inteiros
Represente 407 em BCD e em binário puro. Compare o número de bits utilizados e explique a diferença.
Represente −45 em 8 bits nas três formas: sinal-magnitude, complemento a um e complemento a dois.
Efetue 01001010₂ − 00011110₂ (74 − 30) em complemento a dois de 8 bits, mostrando os passos.
Em complemento a dois de 8 bits a faixa é de −128 a +127, assimétrica. Explique a origem da assimetria e por que ela é considerada uma vantagem.
Seção 6 — Números fracionários
Obtenha a representação IEEE-754 de precisão simples do valor +6,25.
Explique por que o expoente do IEEE-754 é armazenado em excesso-K em vez de complemento a dois.
Quando é preferível ponto fixo a ponto flutuante? Dê um exemplo de aplicação.
Seção 7 — Multiplicadores binários
Um HD é anunciado como tendo 2 TB. Quanto o sistema operacional mostrará, se ele reportar a capacidade em TiB e em GiB?
Quantos inteiros positivos distintos podem ser representados em uma base B com N algarismos? Aplique o resultado para responder quantas instruções distintas cabem em um opcode de 6 bits.
Referências
Principais (essenciais)
-
SILVA, Gabriel Pereira da. Arquitetura e organização de computadores: uma introdução. Rio de Janeiro: LTC, 2024. Recurso online — Acervo Virtual. Número de chamada: Ac.5063593
- Aula 1 — Sistemas de Representação da Informação (texto de referência desta aula)
-
CAPUANO, Francisco Gabriel. Sistemas digitais: circuitos combinacionais e sequenciais. São Paulo: Érica, 2014. Recurso online — Acervo Virtual. Número de chamada: Ac.5012157
- Sistemas de numeração, códigos e funções lógicas
Aprofundamento (opcionais)
-
DELGADO, José. Arquitetura de computadores. Rio de Janeiro: LTC, 2017. Recurso online — Acervo Virtual. Número de chamada: Ac.5013563
-
STALLINGS, William. Arquitetura e organização de computadores. São Paulo: Pearson Education, 2024. Número de chamada: Ac.132127 (Recomendado para aprofundar aritmética computacional e o padrão IEEE-754.)
-
TOCCI, Ronald J.; WIDMER, Neal S.; MOSS, Gregory L. Sistemas digitais: princípios e aplicações. São Paulo: Pearson Prentice Hall, 2018. Número de chamada: Ac.131146
-
IFRAH, Georges. Os números: a história de uma grande invenção. (Referência histórica citada nesta aula, sobre a origem dos sistemas de numeração.)