Ir para o conteúdo principal

Bases Numéricas e Conversão de Inteiros: O Guia Completo

Autor
Francisco Bustamante
Um químico trabalhando com Ciência de Dados e Programação em Python.
Tabela de conteúdos
Do Zero ao Float - Este artigo faz parte de uma série de artigos.
Parte 1: Esse Artigo

Sistemas computacionais não “entendem” números da mesma forma que nós. Em hardware, toda informação — instruções, endereços, caracteres e valores numéricos — precisa ser codificada em sinais elétricos com poucos estados estáveis. Por isso, a base conceitual da computação digital é o uso de sistemas de numeração, especialmente aqueles que se encaixam naturalmente na eletrônica e na organização de bits.

Na prática, você vai alternar entre representações dependendo do contexto: o binário é a linguagem nativa do circuito; o hexadecimal (e, historicamente, o octal) existem para tornar padrões de bits legíveis; e o decimal continua sendo o sistema mais conveniente para interação humana, leitura e verificação de resultados.

Neste artigo, você vai aprender:

  • o que é notação posicional e como ela funciona;
  • como converter números inteiros entre bases comuns (decimal, binário, octal e hexadecimal);
  • quando é possível acelerar conversões usando agrupamento/expansão de dígitos (bases relacionadas por potência).

O foco aqui é em números inteiros não negativos. Em artigos futuros, trataremos conversões com sinal (incluindo representação em complemento de dois) e números em ponto flutuante.

Algumas definições rápidas antes de começar:

  • Binário (base-2) é a base dos sistemas digitais: bits e operações lógicas trabalham diretamente com 0 e 1.
  • Hexadecimal (base-16) e Octal (base-8) são usados para compactar e “enxergar” sequências binárias sem perder correspondência com os bits.
  • O sistema Decimal (base-10) é o padrão do dia a dia e aparece naturalmente em entradas/saídas, documentação e validação manual.
  • Outros sistemas, como o Duodecimal (base-12), são menos comuns em computação geral, mas aparecem em aplicações e contextos específicos.

Tipos de Sistema de Numeração
#

Um sistema de numeração é definido pela sua base (radix), que determina quantos símbolos existem e quais são os pesos de cada posição. A seguir estão os quatro sistemas mais frequentes em computação.

1. Sistema de Numeração Decimal
#

  • O sistema Decimal é um sistema de numeração de base 10.
  • Ele usa dez dígitos: 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9.
  • O valor posicional de cada dígito é uma potência de 10 (por exemplo, \(10^{0}\), \(10^{1}\), \(10^{2}\)).
  • É o sistema padrão para contagem e cálculos do dia a dia.

2. Sistema de Numeração Binário
#

  • O sistema Binário é um sistema de numeração de base 2.
  • Ele usa dois dígitos: 0 e 1.
  • O valor posicional de cada dígito é uma potência de 2 (por exemplo, \(2^{0}\), \(2^{1}\), \(2^{2}\)).
  • O sistema Binário é a base para representação de dados em computadores e eletrônica digital.

3. Sistema de Numeração Octal
#

  • O sistema Octal é um sistema de numeração de base 8.
  • Ele usa oito dígitos: 0, 1, 2, 3, 4, 5, 6 e 7.
  • O valor posicional de cada dígito é uma potência de 8 (por exemplo, \(8^{0}\), \(8^{1}\), \(8^{2}\)).
  • Ele é frequentemente usado para simplificar a representação de números binários agrupando-os em conjuntos de três bits.

4. Sistema de Numeração Hexadecimal
#

  • O sistema Hexadecimal é um sistema de numeração de base 16.
  • Ele usa dezesseis símbolos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E e F.
  • Os símbolos A–F representam valores decimais de 10 a 15 (por exemplo, \(A = 10\), \(B = 11\), …, \(F = 15\)).
  • O valor posicional de cada dígito é uma potência de 16 (por exemplo, \(16^{0}\), \(16^{1}\), \(16^{2}\)).
  • O Hexadecimal simplifica o binário ao representar cada 4 bits como um dígito (0–F).

Resumindo:

Sistema (base) Símbolos disponíveis Valor posicional (pesos) Uso típico em computação Conversão rápida com binário (quando aplicável)
Decimal (10) 0–9 potências de 10: \(10^0,10^1,10^2,\dots\) Interação humana, leitura, documentação, validação manual de resultados
Binário (2) 0–1 potências de 2: \(2^0,2^1,2^2,\dots\) Representação nativa em hardware (bits), operações lógicas
Octal (8) 0–7 potências de 8: \(8^0,8^1,8^2,\dots\) Legibilidade/compactação de bits (contexto histórico e alguns sistemas) \(8=2^3\): 1 dígito octal ↔ 3 bits
Hexadecimal (16) 0–9, A–F (\(A=10,\dots,F=15\)) potências de 16: \(16^0,16^1,16^2,\dots\) Endereços, dumps de memória, padrões de bits legíveis (muito comum) \(16=2^4\): 1 dígito hex ↔ 4 bits

Vamos entender melhor o que queremos dizer com valor posicional.

Números inteiros e notação posicional
#

Como destacado anteriormente, este artigo foca em números inteiros e suas representações em diferentes bases. A notação posicional é o método mais comum para representar números em qualquer base: o valor de cada dígito depende de sua posição, e cada posição tem peso dado por uma potência da base.

Em termos práticos, essa ideia explica por que:

  • a expansão posicional permite transformar um número de qualquer base para decimal (somando pesos);
  • as divisões sucessivas “extraem” os dígitos do número na base desejada, do menos significativo para o mais significativo.

Um número \(N\) em uma base \(b\) pode ser representado como:

$$ N_b = \sum_{i=0}^{n} d_i \cdot b^i = d_n \cdot b^n + d_{n-1} \cdot b^{n-1} + ... + d_1 \cdot b^1 + d_0 \cdot b^0 $$

onde \(d_i\) são os dígitos do número e \(b\) é a base. Cada dígito \(d_i\) deve satisfazer \(0 \leq d_i < b\).

Observação: a mesma lógica vale para a parte fracionária, usando potências negativas (\(b^{-1}, b^{-2}, ...\)). Como aqui o foco é em inteiros, voltaremos a frações e ponto flutuante em artigos específicos.

Por exemplo, o número \(123_{10}\) em base decimal pode ser expandido como:

$$ 123_{10} = 1 \cdot 10^2 + 2 \cdot 10^1 + 3 \cdot 10^0 = 100 + 20 + 3 $$

A partir daqui, vamos usar neste artigo as seguintes notações para bases:

  • \(s\) como base de origem (s de source);
  • \(r\) como base de destino (r de result);
  • \(b\) apenas quando a base for genérica em uma fórmula.

Métodos de Conversão
#

Para converter números inteiros entre bases, não é necessário decorar dezenas de regras. Na verdade, precisamos dominar apenas dois métodos fundamentais, usando o sistema Decimal como uma “ponte” ou “tradutor universal”:

  1. Expansão Posicional (Multiplicação): Usado quando queremos descobrir quanto vale um número de qualquer base em Decimal.
  2. Divisões Sucessivas: Usado quando temos um valor em Decimal e queremos codificá-lo para outra base.

1. De qualquer base para Decimal (Expansão)
#

Quando você tem um número em binário, octal ou hexadecimal e quer saber o valor numérico dele (“quanto isso vale no meu dia a dia?”), você usa a Expansão Posicional.

O processo é simples: somar o valor de cada dígito multiplicado pelo peso da sua posição (a base elevada à potência da posição).

$$ N_{10} = \sum (\text{dígito} \times \text{base}^{\text{posição}}) $$
Exemplo: Converter \(1101_2\) para Decimal

Identificamos a base (\(2\)) e as posições (começando de 0 da direita para a esquerda).

$$ \begin{align*} 1101_2 & = 1 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 \\ & = 1 \cdot 8 + 1 \cdot 4 + 0 \cdot 2 + 1 \cdot 1 \\ & = 8 + 4 + 0 + 1 \\ & = 13_{10} \end{align*} $$

Dica de verificação: em binário, \(1101_2\) deve estar entre \(8_{10}\) (representado como \(1000_2\)) e \(16_{10}\) (representado como \(10000_2\)), então \(13_{10}\) faz sentido.

Exemplo: Converter \(2F_{16}\) para Decimal

Lembre-se que em Hexadecimal, \(F = 15\).

$$ \begin{align*} 2F_{16} & = 2 \cdot 16^1 + 15 \cdot 16^0 \\ & = 32 + 15 \\ & = 47_{10} \end{align*} $$

2. De Decimal para qualquer base (Divisões Sucessivas)
#

Quando você tem um número decimal e precisa representá-lo em binário, octal ou qualquer outra base, o método padrão é o das Divisões Sucessivas.

O algoritmo é:

  1. Divida o número decimal pela base de destino.
  2. Anote o resto (ele será um dos dígitos).
  3. Pegue o quociente e divida novamente pela base.
  4. Repita até que o quociente seja zero.
  5. O resultado é formado pelos restos lidos do último para o primeiro (de baixo para cima).
Exemplo: Converter \(45_{10}\) para Binário (Base 2)

$$ \begin{align*} 45 \div 2 & = 22 \quad & \text{resto } \mathbf{1} \\ 22 \div 2 & = 11 \quad & \text{resto } \mathbf{0} \\ 11 \div 2 & = 5 \quad & \text{resto } \mathbf{1} \\ 5 \div 2 & = 2 \quad & \text{resto } \mathbf{1} \\ 2 \div 2 & = 1 \quad & \text{resto } \mathbf{0} \\ 1 \div 2 & = 0 \quad & \text{resto } \mathbf{1} \end{align*} $$

Lendo de baixo para cima: \(101101_2\).

Dica de verificação: reconverta \(101101_2\) para decimal via expansão posicional e confira se volta em \(45_{10}\).

3. O Método da “Ponte Decimal” (Base \(A \to\) Base \(B\))
#

E se quisermos converter de Base 9 para Base 4? Ou de Base 5 para Base 7?

Como essas bases não conversam diretamente entre si, usamos o Decimal como intermediário. O processo tem duas etapas:

  1. Origem \(\to\) Decimal (usando Expansão).
  2. Decimal \(\to\) Destino (usando Divisões).
Exemplo: Converter \(87_9\) para Base 4

Passo 1: Base 9 para Decimal

$$ 87_9 = 8 \cdot 9^1 + 7 \cdot 9^0 = 72 + 7 = \mathbf{79_{10}} $$

Passo 2: Decimal (79) para Base 4

$$ \begin{align*} 79 \div 4 & = 19 \quad & \text{resto } \mathbf{3} \\ 19 \div 4 & = 4 \quad & \text{resto } \mathbf{3} \\ 4 \div 4 & = 1 \quad & \text{resto } \mathbf{0} \\ 1 \div 4 & = 0 \quad & \text{resto } \mathbf{1} \end{align*} $$

Lendo os restos de baixo para cima: \(1033_4\).

Logo, \(87_9 = 1033_4\).

Mais um exemplo:

Exemplo: Converter \(2F_{16}\) para base \(2\)
  1. Converter de hexadecimal para decimal:

    $$ 2F_{16} = 2 \times 16^1 + F \times 16^0 = 2 \times 16 + 15 \times 1 = 47_{10} $$
  2. Converter de decimal para binário:

    $$ \begin{align*} 47 \div 2 & = 23 & \quad \text{resto } 1 \\ 23 \div 2 & = 11 & \quad \text{resto } 1 \\ 11 \div 2 & = 5 & \quad \text{resto } 1 \\ 5 \div 2 & = 2 & \quad \text{resto } 1 \\ 2 \div 2 & = 1 & \quad \text{resto } 0 \\ 1 \div 2 & = 0 & \quad \text{resto } 1 \end{align*} $$

Lendo de baixo para cima: \(2F_{16} = 101111_2\).

Dica de verificação: você pode conferir o resultado em hexadecimal agrupando \(101111_2\) em 4 bits com padding (preenchimento com zeros) à esquerda (\(0010\,1111\)).

Exemplo: Converter \(1101_2\) para hexadecimal (\(16\))
  1. Converter para decimal:

    $$ 1101_2 = 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 13_{10} $$
  2. Converter decimal para hexadecimal:

    $$ 13_{10} = D_{16} $$

Assim, \(1101_2 = D_{16}\).

Dica de verificação: como 4 bits formam 1 dígito hexadecimal, \(1101_2\) deve mesmo mapear para \(D_{16}\).

Estes dois últimos casos em específico podem ser simplificado, sem ter que passar por decimal, pois \(16 = 2^4\). Assim, cada dígito hexadecimal corresponde exatamente a 4 bits binários. Veja a seção Facilitando a Conversão Quando as Bases São Relacionadas por Potência para mais detalhes. Mas a abordagem “via decimal” funciona para qualquer par de bases.

Resumo Geral dos Métodos
#

Objetivo Método
Descobrir o valor (Qualquer \(\to\) Decimal) Expansão Posicional (Soma das multiplicações)
Codificar o valor (Decimal \(\to\) Qualquer) Divisões Sucessivas (Ler restos de baixo para cima)
Troca de representação (Base \(A \to\) Base \(B\)) Ponte via Decimal (Expansão \(\to\) Divisão)

Erros comuns (e como evitar)
#

  • Ler restos na ordem errada: em divisões sucessivas, o resultado é lido de baixo para cima.
  • Esquecer a base no subíndice: sempre mantenha a notação (\(N_s\) e \(N_r\)) para não misturar interpretações.
  • No agrupamento (binário→octal/hex), agrupar a partir da direita; se faltar bits no grupo mais à esquerda, completar com zeros (padding).
  • No “via decimal”, esquecer de converter símbolos como \(A\)–\(F\) para valores \(10\)–\(15\).

Facilitando a Conversão Quando as Bases São Relacionadas por Potência
#

Se \(s\) e \(r\) possuem uma relação de potência (\(s = r^k\) ou \(r = s^k\)), você pode converter diretamente agrupando ou expandindo dígitos, sem fazer contas longas.

A regra prática mais comum em computação é:

  • se você está indo do binário para uma base maior, agrupe bits;
  • se você está indo de uma base maior para o binário, expanda cada dígito para bits.

Caso 1: Base Menor para Base Maior (\(s < r\))
#

Se \(r = s^k\), cada dígito em base \(r\) corresponde exatamente a \(k\) dígitos na base \(s\). Em computação, o caso clássico é \(s=2\) e \(r \in \{8,16\}\), onde:

  • \(8 = 2^3\) (logo \(k=3\));
  • \(16 = 2^4\) (logo \(k=4\)).
Exemplo: Conversão de Binário (\(2\)) para Octal (\(8\))

Sabemos que \(8 = 2^3\), então cada grupo de 3 bits representa um dígito octal.

Passo 1: Separar o número binário em blocos de 3 bits da direita para a esquerda

$$ 101011_2 $$

Agrupamos:

$$ \mathbf{101} \quad \mathbf{011} $$

Passo 2: Converter cada grupo para octal

$$ 101_2 = 5_8, \quad 011_2 = 3_8 $$

Resultado final:

$$ 101011_2 = 53_8 $$
Exemplo: Conversão de Binário (\(2\)) para Hexadecimal (\(16\))

Como \(16 = 2^4\), agrupamos os dígitos de 4 em 4.

Passo 1: Separar o número binário em blocos de 4 bits

$$ 11010101_2 $$

Agrupamos:

$$ \mathbf{1101} \quad \mathbf{0101} $$

Passo 2: Converter cada grupo para hexadecimal

$$ 1101_2 = D_{16}, \quad 0101_2 = 5_{16} $$

Resultado final:

$$ 11010101_2 = D5_{16} $$

Exemplo com outras bases:

Exemplo: Converter \(2120_{3}\) para base \(9\)

Como \(9 = 3^{2}\), cada dígito em base \(9\) corresponde a um bloco de 2 dígitos em base \(3\).

Passo 1: Agrupar os dígitos de 2 em 2, da direita para a esquerda:

$$ 2120_{3} \;\Rightarrow\; \mathbf{21}\;\mathbf{20} $$

Passo 2: Converter cada bloco (em base \(3\)) para um dígito (em base \(9\)):

$$ \begin{align*} 21_{3} & = 2\cdot 3^{1} + 1\cdot 3^{0} = 6 + 1 = 7_{10} = 7_{9} \\ 20_{3} & = 2\cdot 3^{1} + 0\cdot 3^{0} = 6 + 0 = 6_{10} = 6_{9} \end{align*} $$

Resultado final: \(2120_{3} = 76_{9}\)

Caso 2: Base Maior para Base Menor (\(s > r\))
#

Se \(s = r^k\), você pode expandir cada dígito da base maior em \(k\) dígitos da base menor. Em computação, novamente o caso mais comum é expandir octal/hexadecimal para binário.

Exemplo: Conversão de Octal (\(8\)) para Binário (\(2\))

Como \(8 = 2^3\), cada dígito octal pode ser escrito como 3 dígitos binários.

Passo 1: Substituir cada dígito octal por sua forma binária de 3 bits

$$ 753_8 $$

Expandimos:

$$ 7_8 = 111_2, \quad 5_8 = 101_2, \quad 3_8 = 011_2 $$

Resultado final:

$$ 753_8 = 111101011_2 $$
Exemplo: Conversão de Hexadecimal (\(16\)) para Binário (\(2\))

Como \(16 = 2^4\), cada dígito hexadecimal pode ser escrito como 4 dígitos binários.

Passo 1: Substituir cada dígito hexadecimal por sua forma binária de 4 bits

$$ 4F2_{16} $$

Expandimos:

$$ 4_{16} = 0100_2, \quad F_{16} = 1111_2, \quad 2_{16} = 0010_2 $$

Resultado final:

$$ 4F2_{16} = 010011110010_2 $$

Resumo das estratégias quando as bases são relacionadas por potência
#

Conversão Método Simplificado
Binário \(\to\) Octal (\(2 \to 8\)) Agrupar em blocos de 3 bits
Binário \(\to\) Hexadecimal (\(2 \to 16\)) Agrupar em blocos de 4 bits
Octal \(\to\) Binário (\(8 \to 2\)) Expandir cada dígito octal em 3 bits
Hexadecimal \(\to\) Binário (\(16 \to 2\)) Expandir cada dígito hexadecimal em 4 bits

Fluxograma de Escolha de Método
#

Para facilitar a escolha do método adequado para conversão entre bases, aqui está um fluxograma resumido:

flowchart TD
    Start([Converter da base s
para base r]) --> CheckDest{r = 10?} %% Caso 1: Destino é Decimal CheckDest -- Sim --> Method1[Método 1: Expansão Posicional
Multiplicar cada dígito pelo
peso da sua posição] Method1 --> Result([Resultado em Decimal]) %% Caso 2: Origem é Decimal CheckDest -- Não --> CheckOrig{s = 10?} CheckOrig -- Sim --> Method2[Método 2: Divisões Sucessivas
Dividir N sucessivamente por r
e ler os restos de baixo para cima] Method2 --> Result2([Resultado na Base r]) %% Caso 3: Bases Arbitrárias (Ponte ou Atalho) CheckOrig -- Não --> CheckPower{sk = r?
Ou rk = s?
Ex: 2, 8, 16} %% Atalho CheckPower -- Sim --> Method3a[Atalho: Agrupamento ou Expansão
Substituir dígitos por bits ou
agrupar bits em dígitos] Method3a --> Result2 %% Ponte Decimal CheckPower -- Não --> Method3b[Método 3: Ponte Decimal
1. Converter s para 10 Expansão
2. Converter 10 para r Divisão] Method3b --> Result2 %% Estilização para ficar bonito no blog style Start fill:#f9f,stroke:#333,stroke-width:2px,color:black style Result fill:#ccf,stroke:#333,stroke-width:2px,color:black style Result2 fill:#ccf,stroke:#333,stroke-width:2px,color:black style Method1 fill:#e1f7d5,stroke:#333,color:black style Method2 fill:#e1f7d5,stroke:#333,color:black style Method3a fill:#fff4e6,stroke:#f66,stroke-width:2px,stroke-dasharray: 5 5,color:black style Method3b fill:#e1f7d5,stroke:#333,color:black

Explicação visual das cores usadas no gráfico:

  • Verde claro: Os métodos “padrão” (algoritmos matemáticos).
  • Laranja/Tracejado: O atalho (um caminho especial).
  • Roxo: Pontos de início e fim.

Representação Prática: Bases Numéricas em Python
#

Na matemática, usamos subíndices (como \(101_2\) ou \(75_{16}\)) para indicar a base. No entanto, na hora de programar, não temos como digitar subíndices facilmente. Por isso, linguagens de programação adotam prefixos para indicar ao interpretador em qual base o número está escrito.

Como o Python é a linguagem principal abordada neste site, veja como representar e manipular essas bases nativamente:

Literais (Escrevendo números no código)
#

Para escrever um número inteiro diretamente em uma base específica, usamos o dígito 0 seguido de uma letra identificadora:

  • Binário: Prefixo 0b (Ex: 0b1010)
  • Octal: Prefixo 0o (Ex: 0o52)
  • Hexadecimal: Prefixo 0x (Ex: 0x2F)

Ao digitar esses valores, o Python os interpreta e armazena internamente como inteiros normais.

# O Python entende todos estes valores como o mesmo número (42)
n_dec = 42
n_bin = 0b101010
n_oct = 0o52
n_hex = 0x2A

print(n_dec == n_bin == n_oct == n_hex) # Saída: True
print(n_hex) # Saída: 42 (O print padrão sempre mostra em decimal)

Funções de Conversão
#

Se você precisa converter um número para uma string formatada em outra base, ou converter uma string para um inteiro, use as funções nativas:

Função Descrição Exemplo Entrada Exemplo Saída
bin(x) Converte inteiro para string binária bin(10) '0b1010'
oct(x) Converte inteiro para string octal oct(10) '0o12'
hex(x) Converte inteiro para string hexadecimal hex(10) '0xa'
int(s, base) Converte string de base (b) para inteiro int('101', 2) 5

Observações úteis:

  • int(s, base) aceita bases de 2 a 36 (além de base=0, que tenta detectar a base pelo prefixo, como 0b, 0o, 0x).
  • Com base explícita (por exemplo, 2 ou 16), a string não deve incluir prefixo. Ex.: int('101', 2) funciona, mas int('0b101', 2) gera erro. Se a string tiver prefixo, use int('0b101', 0).

Exemplo prático de uso:

valor = 255

# Formatando para visualização (usando f-strings modernas)
# :b para binário, :o para octal, :x para hex minúsculo, :X para hex maiúsculo
# Use # para incluir o prefixo (0b, 0o, 0x) na saída: {valor:#b}, {valor:#x}, etc.
print(f"Decimal: {valor}")      # 255
print(f"Binário: {valor:b}")    # 11111111
print(f"Octal:   {valor:o}")    # 377
print(f"Hex:     {valor:X}")    # FF
print(f"Hex c/ prefixo: {valor:#x}")  # 0xff

# Lendo entrada do usuário (que sempre vem como string)
entrada_usuario = "1A"
numero = int(entrada_usuario, 16)
print(numero) # Imprime 26

Exercício de Algoritmos: Implementando “Na Mão”
#

Embora as funções nativas do Python (int(), bin(), etc.) sejam altamente otimizadas e devam ser usadas em código de produção, implementar esses conversores do zero é um excelente exercício de lógica de programação para entender o que acontece “por baixo do capô”.

Abaixo, apresentamos implementações didáticas dos métodos de Expansão Posicional e Divisões Sucessivas.

Atenção

Este código é puramente educacional. Em projetos reais, sempre prefira as funções nativas da linguagem, que são escritas em C e muito mais rápidas.

# Mapeamento para dígitos maiores que 9 (A=10, B=11, etc.)
DIGITOS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

def qualquer_base_para_decimal(numero_str: str, base_origem: int) -> int:
    """
    Implementa o método da Expansão Posicional.
    Converte uma string numérica de base_origem para inteiro (decimal).
    """
    resultado_decimal = 0
    # Invertemos a string para começar da potência 0 (direita para esquerda)
    # Ex: "101" invertido vira "101" -> índices 0, 1, 2 correspondem a 2^0, 2^1, 2^2
    numero_invertido = numero_str[::-1].upper()
    
    for posicao, digito_char in enumerate(numero_invertido):
        # Descobre o valor numérico do caractere (ex: 'A' -> 10)
        valor_digito = DIGITOS.index(digito_char)
        
        if valor_digito >= base_origem:
            raise ValueError(f"Dígito {digito_char} inválido para base {base_origem}")
            
        # Acumula: dígito * (base ^ posição)
        resultado_decimal += valor_digito * (base_origem ** posicao)
        
    return resultado_decimal

def decimal_para_qualquer_base(numero_dec: int, base_destino: int) -> str:
    """
    Implementa o método das Divisões Sucessivas.
    Converte um inteiro (decimal) para uma string na base_destino.
    """
    if numero_dec == 0:
        return "0"
    
    restos = []
    dividendo = numero_dec
    
    while dividendo > 0:
        # Pega o resto da divisão
        resto = dividendo % base_destino
        
        # Pega o quociente para a próxima iteração
        dividendo = dividendo // base_destino
        
        # Converte o resto num caractere (ex: 15 -> 'F') e guarda
        restos.append(DIGITOS[resto])
    
    # O algoritmo exige ler os restos de baixo para cima (do último para o primeiro)
    return "".join(restos[::-1])

# --- Testando as funções ---

# Teste 1: Binário para Decimal (Expansão)
binario = "1101"
dec = qualquer_base_para_decimal(binario, 2)
print(f"Expansão: {binario}_2 para decimal é {dec}") 
# Saída: 13

# Teste 2: Decimal para Hexadecimal (Divisão)
decimal = 47
hexa = decimal_para_qualquer_base(decimal, 16)
print(f"Divisão: {decimal}_10 para hexa é {hexa}") 
# Saída: 2F

# Teste 3: A Ponte (Base 9 para Base 4)
# Usamos o decimal como intermediário
valor_base9 = "87"
passo1_decimal = qualquer_base_para_decimal(valor_base9, 9)
passo2_base4 = decimal_para_qualquer_base(passo1_decimal, 4)
print(f"Conversão: {valor_base9}_9 -> {passo1_decimal}_10 -> {passo2_base4}_4")
# Saída: 87_9 -> 79_10 -> 1033_4

Próximos passos
#

Neste ponto, você já tem duas ferramentas essenciais: (1) a expansão posicional, que permite interpretar um número em qualquer base, e (2) as divisões sucessivas, que permitem construir a representação em outra base. Além disso, quando as bases são relacionadas por potência (como \(2 \leftrightarrow 8\) e \(2 \leftrightarrow 16\)), você pode converter quase “de cabeça” usando agrupamento e expansão.

Se você quiser consolidar de verdade, pratique com a regra de ouro: sempre valide o resultado fazendo a conversão inversa. Comece com poucos exercícios (por exemplo, 5 conversões em cada direção) e tente alternar os métodos: em um dia, use expansão posicional; no outro, use divisões sucessivas; depois, use apenas agrupamento/expansão quando couber.

Nos próximos artigos, a ideia é avançar pelos temas que aparecem o tempo todo em Ciência da Computação. Primeiro, veremos como o hardware realiza operações aritméticas — soma e subtração — em qualquer base. Em seguida, entenderemos como representar inteiros com sinal (incluindo o Complemento de Dois) e como lidar com os limites da memória (Overflow). Por fim, mergulharemos nos números reais e na representação em ponto flutuante. Esses tópicos explicam, por exemplo, por que existem overflow, underflow e diferenças sutis entre “o número” e “o que cabe no registrador”.

Se você quiser, deixe nos comentários quais conversões você mais erra (decimal↔binário, binário↔hex, etc.) e eu incluo uma seção curta de “erros comuns + checagens rápidas” com exemplos adicionais.

Até a próxima!

Do Zero ao Float - Este artigo faz parte de uma série de artigos.
Parte 1: Esse Artigo

Relacionados

Séries infinitas - Cálculo com Python e SymPy

Um bom tempo do estudo de cálculo é destinado às chamadas séries infinitas. Mas, afinal, o que são séries infinitas? E qual sua relação com o paradoxo de Aquiles e a tartaruga, um dos chamados paradoxos de Zenão de Eleia, filósofo grego? Qual a relação com quântica e o princípio da incerteza? E onde entra Python nisto tudo? É o que descobriremos neste artigo.