Representando números


A forma padronizada, utilizada hoje, para representar números é chamada de sistema de representação posicional em base 10. Isso significa, de forma simplificada, que cada dígito utilizado do número tem um “peso”, múltiplo de 10 (mais que isso, uma potência de 10) dependendo de sua posição. Por exemplo, o número 624 pode ser escrito como:

624=6×102+2×101+4×100624 = 6 \times 10^2 + 2 \times 10^1 + 4 \times 10^0

Decomposição de 624 em dígitos, na base decimal

O dígito 6 ocupa a segunda posição — com contagem da direita para esquerda, começando no zero. O dígito 6 nessa posição indica que temos uma parcela de 6×102=6006 \times 10^2 = 600 compondo o número.

Dígitos e índices do número 624 representado na base decimal

Para representar um número na base b=10b = 10 são necessários b1=9b-1 = 9 dígitos diferentes (de zero a 9).

Sistema de representação de sinal-valor (não posicional)

Antes de explorar mais os sistemas posicionais, vale citar alguns exemplos de sistemas não posicionais. O exemplo mais comum ainda com algum uso é o sistema de números romanos. Nesse sistema a representação do número não depende da posição, mas sim do valor do símbolo.

No sistema romano são utilizados diferentes símbolos para representar as unidades, potências de 10 e outros valores. Por convenção, se escreve os símbolos com valores mais altos à esquerda, o que permite o uso de notação subtrativa — por exemplo, I representa 1 e X representa 10, porém IX representa o número 9 — um número menor antes de um número maior indica a subtração.

Nesse sistema também são necessários mais e mais símbolos para representar números maiores — em contraste com o sistema posicional, onde números maiores precisam de mais dígitos.

Também não existe um símbolo representando o zero.

Outras bases numéricas

Voltando aos sistemas posicionais, podemos utilizar outras bases (além da decimal). De modo geral, para uma base bb, com b>1b > 1, podemos escrever qualquer inteiro nn como:

n=i=0mdi×bin = \sum_{i=0}^{m} d_i \times b^i

Onde did_i representam os dígitos do número e mm o índice (posição) do dígito mais significativo. A notação (b)(b) ao lado do número indica qual a base utilizada para sua representação.

Ainda utilizando o número 624(10)624_{(10)} como exemplo, vamos obter sua representação em base 4. Para b=4b=4 os dígitos disponíveis são {0,1,2,3}\{0,1,2,3\}. O algoritmo para obtenção é simples: dividimos o número por 4, separando em quociente e resto. Continuamos dividindo o quociente obtido por 4 até chegarmos em zero. A representação na nova base é a sequência de restos obtida.

624 ÷ 4 = 156 resto 0
156 ÷ 4 =  39 resto 0
 39 ÷ 4 =   9 resto 3
  9 ÷ 4 =   2 resto 1
  2 ÷ 4 =   0 resto 2

Desse modo, 624(10)=21300(4)624_{(10)} = 21300_{(4)}. Observe que a construção da representação acontece na ordem inversa da obtenção dos dígitos: os primeiros restos obtidos são os menos significativos. Para verificar que 21300(4)21300_{(4)} realmente representa 624(10)624_{(10)} podemos calcular sua decomposição:

21300(4)=2×44+1×43+3×42+0×41+0×4021300_{(4)} = 2 \times 4^4 + 1 \times 4^3 + 3 \times 4^2 + 0 \times 4^1 + 0 \times 4^0 =2×256+1×64+3×16=512+64+48=624= 2 \times 256 + 1 \times 64 + 3 \times 16 = 512 + 64 + 48 = 624

Bases maiores que 10

Para b>10b > 10 é necessária a inclusão de símbolos representando outras quantidades. O sistema hexadecimal (base 16) utiliza dígitos de 0 a 9 mais 6 letras (A a F) representando as quantidades de 10 a 15.

Como exemplo, convertendo 6748(10)6748_{(10)} para base hexadecimal temos:

6748 ÷ 16 = 421 resto 12
 421 ÷ 16 =  26 resto  5
  26 ÷ 16 =   1 resto 10
   1 ÷ 16 =   0 resto  1

A composição do número com base nos restos é 1, 10, 5, 12. Note que aparecem nessa representação os “dígitos” 12 e 10, representados, respectivamente, pelos símbolos C e A, logo temos que 6748(10)=1A5C(16)6748_{(10)} = 1A5C_{(16)}.

Conversão entre bases

Como exemplo, disponibilizei uma classe simples em Python que realiza conversões entre bases numéricas. O código fonte está disponível em github.com/lucasvitti/metanumber.

A classe MetaNumber representa os dígitos de um número em uma base especificada e possui funções internas de conversão para outras bases. Do modo como foi desenvolvida, as conversões entre bases passam, obrigatoriamente, pela representação em base 10 (ou seja, o tamanho dos números “trabalháveis” são limitados pelo valor máximo de uma variável int em Python).

import os

# Altera o diretório de trabalho para o diretório com o código
diretorio = r'C:\Diretorio_com_script'
os.chdir(diretorio)

# Assumindo que o nome do arquivo é MetaNumber.py
from MetaNumber import MetaNumber

n = 624
num = MetaNumber(n)        # Número 624 em base decimal
print(num.to_base(4))      # Resulta em 21300, como visto

num = MetaNumber(6748)     # Número 6748 em base decimal
conv = num.to_base(16)
conv.get_digits()
print(conv)

No exemplo acima testamos as conversões calculadas anteriormente, obtendo, como o esperado, os mesmos resultados.

Exemplo da execução do script acima

Trabalhando em outras bases

No sistema posicional não precisamos nos ater a bases inteiras positivas. Podemos explorar bases negativas e até mesmo não inteiras (racionais ou irracionais). Embora o algoritmo de conversão mude um pouco para as bases não naturais (i.e., bases que não pertencem ao conjunto dos números naturais) a ideia geral da representação permanece a mesma.

Como exemplo, vamos converter, via a classe MetaNumber, o número 624 em base negadecimal, i.e., base 10-10. Pelo script obtemos 624(10)=784(10)624_{(10)} = 784_{(-10)}:

Conversão de 624(10) para base negadecimal

784(10)=7×(10)2+8×(10)1+4×(10)0=7×1008×10+4=70080+4=624784_{(-10)} = 7 \times (-10)^2 + 8 \times (-10)^1 + 4 \times (-10)^0 = 7 \times 100 - 8 \times 10 + 4 = 700 - 80 + 4 = 624

No próximo artigo vou explorar com mais detalhes as bases negativas, especialmente a negadecimal.