College Online
0%

Representação de Dados

Módulo 3 · Aula 1 ~18 min de leitura Nível: Intermediário

Vídeo da aula estará disponível em breve

Sistemas Numéricos

Computadores operam em binário (base 2): cada fio, cada transistor, cada célula de memória está em um de dois estados — 0 ou 1. Mas para humanos, binário é difícil de ler. Por isso usamos hexadecimal (base 16) como notação compacta: cada dígito hex representa exatamente 4 bits.

Conversões entre Bases
Decimal   Binário      Octal   Hexadecimal
───────   ──────────   ─────   ───────────
  0       0000         0       0
  1       0001         1       1
  5       0101         5       5
  8       1000         10      8
  10      1010         12      A
  15      1111         17      F
  16      10000        20      10
  42      101010       52      2A
  255     11111111     377     FF
  256     100000000    400     100

Conversão rápida binário ↔ hex:
  Agrupe de 4 em 4 bits (da direita para esquerda):
  1010 1100 0011 1111 = AC3F₁₆

  Cada grupo de 4 bits = 1 dígito hex:
  0000=0  0001=1  0010=2  0011=3  0100=4  0101=5
  0110=6  0111=7  1000=8  1001=9  1010=A  1011=B
  1100=C  1101=D  1110=E  1111=F

Notações no código:
  Binário:      0b10101100  (prefixo 0b)
  Octal:        0254        (prefixo 0)
  Decimal:      172         (sem prefixo)
  Hexadecimal:  0xAC        (prefixo 0x)

Cada base tem sua utilidade: decimal para humanos, binário para o hardware, hex para programadores que precisam visualizar padrões de bits (endereços de memória, cores, instruções codificadas).

Complemento a 2: Inteiros com Sinal

Como representar números negativos em binário? A solução universalmente adotada é o complemento a 2. A ideia é elegante: o bit mais significativo (MSB) tem peso negativo.

Complemento a 2 — 4 bits
Binário   Unsigned   Complemento a 2
────────  ─────────  ────────────────
0000      0          0
0001      1          +1
0010      2          +2
0011      3          +3
0100      4          +4
0101      5          +5
0110      6          +6
0111      7          +7     ← maior positivo
1000      8          -8     ← menor negativo (assimétrico!)
1001      9          -7
1010      10         -6
1011      11         -5
1100      12         -4
1101      13         -3
1110      14         -2
1111      15         -1

Fórmula (N bits):
  Valor = -b_{N-1} × 2^{N-1} + b_{N-2} × 2^{N-2} + ... + b_0 × 2^0

Exemplo (8 bits): 1101 0110
  = -1×128 + 1×64 + 0×32 + 1×16 + 0×8 + 1×4 + 1×2 + 0×1
  = -128 + 64 + 16 + 4 + 2
  = -42

Intervalo com N bits:
  Mínimo: -2^{N-1}     (ex: -128 para 8 bits, -2147483648 para 32 bits)
  Máximo: 2^{N-1} - 1   (ex: +127 para 8 bits, +2147483647 para 32 bits)

Para negar um número em complemento a 2: inverta todos os bits e some 1.

Negação em Complemento a 2
Exemplo: negar +5 (8 bits)
  +5  = 0000 0101
  Inverte: 1111 1010
  Soma 1:  1111 1011  = -5 ✓

Verificação: 5 + (-5) deve dar 0:
    0000 0101    (+5)
  + 1111 1011    (-5)
  ──────────
  1 0000 0000    = 0 (o carry-out é ignorado em 8 bits)

Por que complemento a 2 é genial:
  1. Subtração = soma com o negado (hardware reusa o somador!)
  2. Apenas uma representação para zero (diferente de sinal-magnitude)
  3. Comparação de magnitude funciona para positivos sem hardware extra

Extensão de Sinal

Quando precisamos expandir um valor de menos bits para mais bits (ex: imediato de 16 bits para registrador de 32 bits), usamos extensão de sinal: replicamos o bit de sinal para preencher os bits superiores.

Extensão de Sinal — Exemplos
# Positivo: estender +5 de 8 bits para 16 bits
  8 bits:  0000 0101                    (+5)
  16 bits: 0000 0000 0000 0101          (+5) ✓
  Regra: MSB = 0, preenche com 0s

# Negativo: estender -5 de 8 bits para 16 bits
  8 bits:  1111 1011                    (-5)
  16 bits: 1111 1111 1111 1011          (-5) ✓
  Regra: MSB = 1, preenche com 1s

# Onde isso acontece no MIPS:
# - addi, slti: imediato de 16 bits → extensão de sinal para 32 bits
# - lb (load byte): byte de 8 bits → extensão de sinal para 32 bits
# - lbu (load byte unsigned): extensão com ZEROS (zero-extension)
# - beq/bne: offset de 16 bits → extensão de sinal para 32 bits

# CUIDADO: andi, ori NÃO fazem extensão de sinal!
# Eles fazem zero-extension (preenchem com 0s).
# andi $t0, $s1, 0xFFFF  → AND com 0x0000FFFF (não 0xFFFFFFFF)

Overflow: Quando os Bits Não São Suficientes

Overflow ocorre quando o resultado de uma operação excede o intervalo representável. Em complemento a 2 com 32 bits, somar dois positivos grandes pode dar um "resultado negativo" — isso é overflow.

Detecção de Overflow
# Overflow em adição (4 bits, intervalo -8 a +7):
  0101 (+5)
+ 0100 (+4)
──────
  1001 (-7 em complemento a 2!)  ← OVERFLOW! Resultado correto seria +9

# Regras de detecção:
# Overflow ocorre quando:
#   (+) + (+) = (-)    ← soma de positivos dá negativo
#   (-) + (-) = (+)    ← soma de negativos dá positivo
#
# Overflow NÃO ocorre quando:
#   (+) + (-) = qualquer  ← sinais diferentes nunca causam overflow
#   (-) + (+) = qualquer  ← sinais diferentes nunca causam overflow

# No MIPS:
# - add, addi, sub: GERAM exceção (trap) em overflow
# - addu, addiu, subu: IGNORAM overflow (unsigned, sem trap)
#
# Na prática, compiladores C usam addu/addiu porque C define
# overflow de inteiros como undefined behavior, e a exceção
# causaria um crash inesperado.

# Detecção por hardware:
# Overflow = Carry_in do MSB XOR Carry_out do MSB
# Se esses dois carries diferem, houve overflow.

Representação de Caracteres

Computadores representam texto como números. Dois padrões dominam:

ASCII e Unicode
# ASCII (7 bits, 128 caracteres):
# Suficiente para inglês, insuficiente para o resto do mundo.

Char  Decimal  Hex   Binário
────  ───────  ────  ────────
'0'     48     0x30  011 0000    ← Dígitos: 0x30–0x39
'9'     57     0x39  011 1001
'A'     65     0x41  100 0001    ← Maiúsculas: 0x41–0x5A
'Z'     90     0x5A  101 1010
'a'     97     0x61  110 0001    ← Minúsculas: 0x61–0x7A
'z'    122     0x7A  111 1010
' '     32     0x20  010 0000    ← Espaço
'\n'    10     0x0A  000 1010    ← Nova linha
'\0'     0     0x00  000 0000    ← Terminador de string em C

# Truque útil: 'a' - 'A' = 32 = 0x20 (bit 5)
# Para converter maiúscula → minúscula: OR com 0x20
# Para converter minúscula → maiúscula: AND com 0xDF (NOT 0x20)

# Unicode (UTF-8, UTF-16, UTF-32):
# UTF-8: compatível com ASCII (1 byte para ASCII, 2-4 para o resto)
# UTF-16: 2 bytes para maioria, 4 para emojis e caracteres raros
# UTF-32: 4 bytes fixos por caractere (simples mas desperdiça espaço)
#
# 'ã' em UTF-8: 0xC3 0xA3 (2 bytes)
# 'ç' em UTF-8: 0xC3 0xA7 (2 bytes)
# Em MIPS, strings são sequências de bytes terminadas por '\0' (null).
i
lb vs lbu para strings Se você está carregando caracteres ASCII (0-127), tanto lb quanto lbu funcionam porque o bit 7 é 0. Mas para caracteres estendidos (128-255), use lbu para evitar que a extensão de sinal transforme o valor em negativo.

No harness.os

Representação é sobre codificação de informação — o harness.os codifica conhecimento em tipos estruturados (build, product, operations, domain) da mesma forma que o computador codifica dados em complemento a 2.

Mapeamento: Representação → harness.os
Conceito de Representação        Equivalente no harness.os
──────────────────────────────   ────────────────────────────────────
Binário (2 estados)              Decisões binárias: sim/não, pass/fail,
                                   blocked/unblocked

Complemento a 2 (codificação     Tipagem de conhecimento: o "tipo"
  com convenção de interpretação)  (build/product/ops/domain) determina
                                   como o dado é interpretado, assim
                                   como o formato (signed/unsigned)
                                   determina se 1111 é -1 ou 15

Extensão de sinal (preservar     Herança de contexto: quando um agente
  significado ao expandir)         filho herda contexto do pai, o
                                   "sinal" (intenção/propósito) deve
                                   ser preservado, não truncado

Overflow (limites da              Compaction: quando a context window
  representação)                   "transborda", o harness precisa
                                   detectar e reagir — assim como o
                                   hardware detecta overflow

ASCII → Unicode (evolução da     Evolução do schema: de campos simples
  codificação)                     para estruturas ricas, mantendo
                                   compatibilidade retroativa

Homework

  1. Converta para as outras bases: (a) 0xDEAD em binário e decimal, (b) 0b11001010 em hex e decimal, (c) 173 em binário e hex.
  2. Represente -100 em complemento a 2 com 8 bits. Verifique somando com +100 e mostrando que o resultado é 0 (ignorando o carry-out).
  3. Explique por que a extensão de sinal de 0xFF (8 bits) produz 0xFFFFFFFF (32 bits) com lb, mas 0x000000FF com lbu. Qual é o valor decimal em cada caso?
  4. Determine se ocorre overflow nas seguintes operações em 8 bits (complemento a 2): (a) 100 + 50, (b) -100 + (-50), (c) 100 + (-50), (d) -100 + 50.

Resumo

Verifique seu entendimento

Em complemento a 2 com 8 bits, qual é o valor decimal de 1001 0110?

  • 150
  • -150
  • -96
  • -106