DEV Community

Plínio Ribeiro
Plínio Ribeiro

Posted on

Estudos de Bases Numéricas

Como os números são representados

Em um primeiro momento precisamos entender como os números são representados. Os números são representados por meio do sistema posicional ou notação posicional.

Cada número ou dígito tem seu valor em função da posição que ocupa na sequência numérica e pela base (sistema) que faz parte.

Como escreve os professores Profs. M.Sc. Lucio M. Duarte e Ph.D. Avelino Zorzo:

S*istemas numéricos são posicionais, isto é, cada quantidade é representada em uma única forma, mediante uma certa combinação de símbolos, que têm um significado distinto, segundo sua posição.*

No sistema decimal, como já comentado, cada posição tem um valor intrínseco que
equivale a dez vezes o valor da posição que está imediatamente a sua direita.

Fonte: https://www.inf.pucrs.br/~zorzo/ii/downloads/representacaodedados.pdf

Para sabemos o valor de um número, não basta saber o seu valor individual, mas também qual base ele faz parte e qual a sua posição quando está representando em uma sequência de símbolos.

Vamos partir a explicação do nosso sistema decimal, ou base 10, o qual já estamos acostumados a utilizar.

A exemplo, o número 422.

O qual pode escrito da seguinte forma:

422 = 4x100 + 2x10 + 2x1

Ou da seguinte forma.

422 = 4x10^2 + 2x10^1 + 2x10^0

Explicando:

Para sabermos o valor do 4, que representa 400, temos que saber a sua posição, contando da direita para a esquerda começando com zero. Que nesse caso é 2. Deve observar que consideramos o início da contagem das posições da direita para a esquerda.

Depois multiplicamos 4 pela base, neste caso 10, elevada a sua posição: 2.

*4*10^2 = 4*100 = 400*

Para o valor de 2 que representa 20.

*2*10^1 = 2*10 = 20*

E para o valor de 2 que 2;

*2*10^0 = 2*1 = 2*.

Somamos os resultados: 400 + 20 + 2 = 422.

Concluindo. O valor do símbolo depende da posição que ocupa em relação a todo o conjunto que está representando, bem como da base que está sendo utilizada na representação.

Nesse sentido, podemos obter a partir da seguinte equação de contagem:

$$
D\;=\;\sum_{i\;=\;-n\;}^{p-1}\;d_i\;\times\;r^i\;=d_{p-i}\times r^{p-1}+...+d_1\times r^1+d_0\times r^0+d_{-1}\times r^{-1}+...+d_{-n}\times r^{-n}
$$

Onde:

– D : número;
– r : base ou radix;
– d : dígito (0 ≤ d < r);
– p : quantidade de dígitos na parte inteira;
– n : quantidade de dígitos na parte fracionária;

Por fim uma observação importante:

Observa-se que os sistemas não posicionais dificultavam a representação de números
“grandes”, ou seja, era necessário muitos símbolos para isso. Por outro lado, em um sistema
posicional é possível representar números cada vez maiores com os mesmos símbolos. Outra
grande vantagem do sistema de numeração com valor posicional é que as operações (adição,
subtração, multiplicação e divisão) são de execução bem mais simples.
Em um sistema de numeração posicional o número nove, por exemplo, não tem o
mesmo valor quando está colocado na fileira nas unidades, dezenas, centenas e, assim por
diante. Por exemplo, 959 – No sistema de numeração que usamos hoje, 9 na unidade, tem
como valor posicional nove unidades, na centena o 9 tem valor novecentos. Nesse sistema,
o valor de um algarismo depende da posição que ele ocupa no número.

fonte: https://repositorio.ufgd.edu.br/jspui/bitstream/prefix/1375/1/KatiuceFernandesRocha.pdf

Mais informações:

https://pt.wikipedia.org/wiki/Notação_posicional

https://edisciplinas.usp.br/pluginfile.php/4190820/mod_resource/content/5/PCS3115 2018S1 Sistemas de Numeracao v2.pdf

Bases numéricas

Uma base numérica representa uma quantidade de símbolos possíveis que podemos utilizar para representar um número.

A elas temos a seguinte definição formal.

Definição (Sistema de numeração de base b). Dado um número natural b>1 e o conjunto de símbolos {±,0,1,2,…,b−1}, a sequência de símbolos

$$
(d_nd_{n-1}..d_1d_0,d_{-1}d_{-2}...)_b
$$

representa o número positivo

$$
d_n⋅b^n+d_{n-1}⋅b^{n-1}+\cdots+d_0⋅b^0+d_{-1}⋅b^{-1}+d_{-2}⋅b^{-2}+\cdots
$$

Para representar números negativos usamos o símbolo − a esquerda do numeral.

Mais informações: https://www.ufrgs.br/reamat/CalculoNumerico/livro-py/rdneadm-sistema_de_numeracao_e_mudanca_de_base.html

Assim, escolhemos um número b como base e b símbolos, um para cada número de 0 a b − 1, chamados de algarismos (dígitos). Multiplicando um destes números (algarismos) pelas potências de b (1, b^2, b^3, etc.) e somando-os, conseguimos expressar um número em uma determinada base. Por exemplo, 1352 = 1 · 10^3 + 3 · 10^2 + 5 · 10^1 + 2 · 10^0. Esse número, por exemplo, está representado na base decimal, ou seja, b = 10 .

Assim, os algarismos em qualquer número dado representa um múltiplo de alguma potência da base, potência essa que depende da posição ocupada pelo algarismo. Como exemplo de sistema posicional temos nosso sistema de numeração posicional decimal indo-arábico.

Nesse sistema, por exemplo, 5 em 506 representa 5 · 10^2 ou 500. Agora, 5 em 58 representa 5 x 10^1 ou 50. Observe que o zero é importante para indicar a ausência de alguma potência da base.

Fonte: https://repositorio.ufgd.edu.br/jspui/bitstream/prefix/1375/1/KatiuceFernandesRocha.pdf

São várias as bases numéricas, mas aqui apenas trataremos de estudar algumas mais utilizadas no ambiente de programação. Quais são:

  1. Binária;
  2. Octal;
  3. Decimal;
  4. Hexadecimal;

Em seguida falarei um pouco sobre cada um delas.

Base Binária

No sistema binário ou base binária temos apenas dois símbolos para compor os números. São: 0 e 1. Por isso é chamado de binário em razão da quantidade de símbolos que fazem parte: dois.

São incluídos como símbolos pertencentes a determinada base iniciando-se em 0 até b - 1. Conforme explicado, acima, na definição formal de bases numéricas.

Que neste caso são:

$$
{0, 1}
$$

Onde cada símbolo ou digito tem o seu valor em função do produto da multiplicação dele por 2 elevado a n-enésima posição. Ou seja, construímos a representação de um número qualquer somando as potências de dois presentes na representação.

Como temos apenas 0 e 1 como dígitos disponíveis, quando temos um valor a ser considerado e quando temos zero, dispensa-se a explicação.

Posição 9 8 7 6 5 4 3 2 1 0
Valor 512 256 128 64 32 16 8 4 2 1

Exemplos de representação de números decimais na base binária:

2 = 00010

4 = 00100

10 = 1010

25 = 11001

É a base que os sistemas computacionais entendem e operam. Diferente de nós que utilizamos o sistema decimal. Dado que utilizam os seguintes algarismos: 1 bit (para indicar presença de tensão) e 0 bit (para indicar ausência de tensão).

Toda operação computacional primeiro converte o número para base 2, realiza as operações e depois converte para a base original, qual seja: decimal, hexadecimal ou outra que o usuário esteja utilizando.

Base Octal

Base octal ou base 8 (oito). Nesta base temos 8 (oito) algarismos para representar um número qualquer. São:

$$
{0, 1, 2, 3, 4, 5, 6, 7}
$$

Exemplos de números na base dez e sua representação na base octal:

4 = 4

10 = 12

42 = 52

127 = 177

Mais na frente será demonstrado como é feita a conversão acima exemplificada.

Base Decimal

A base decimal ou base 10 (dez) é que utilizamos no nosso dia a dia. Ela dispõe de 10 (algarismos) para representar os números. Quais são:

$$
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
$$

Base Hexadecimal

A base hexadecimal ou base 16 (dezesseis) são utilizados dezesseis símbolos, que vão de 0 até 9 mais as letras A até F. No qual as letras são equivalentes no sistema decimal aos valores de 10 até 15.

$$
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F}
$$

Exemplos de números na base dez na base hexadecimal:

4 = 4

10 = A

42 = 2A

127 = 2F

Curiosidade: Na linguagem Javascript, pode-se obter o valor decimal de número hexadecimal utilizando o prefixo 0x antes do número na base 16.

console.log(0x7F);
// 127
Enter fullscreen mode Exit fullscreen mode

Conversão de decimal para para as demais bases

Dado um número na base decimal podemos escrevê-lo em qualquer outra base usando sucessivamente a divisão por resto ou Euclidiana. O número que no passo n-ésimo for quociente passa a ser dividendo no passo de ordem n + 1. O processo conclui quando o quociente for zero.

Referências: LINARES, Juan López; BRUNO-ALFONSO, Alexys; BARBOSA, Grazielle Feliciani. Bases numéricas na olimpíada internacional de matemática. Revista Professor de Matemática Online, v. 7, n. 02, 2019.

Continuando a explicação. Após chegarmos a momento que o consciente for zero, alinhamos os restos da divisão na ordem inversa que foram encontrados.

Deve-se atentar que deve utilizar o maior quociente inteiro da divisão.

Converter o número 42 na base 10 para a base 2:

Para o cálculo do resto utilizaremos o operador módulo, representado por %.

42 / 2 = 21 42 % 2 = 0

21 / 2 = 10 21 % 2 = 1

10 / 2 = 5 10 % 2 = 0

5 / 2 = 2 5 % 2 = 1

2 / 2 = 1 2 % 2 = 0

1 / 2 = 0 1 % 2 = 1

Feitas as divisões sucessivas, basta alinhar os restos na ordem inversa: 101010. Assim temos a representada do número 42 na base 10 na base 2.

Este mesmo procedimento é para a conversão para qualquer outra base. Basta substituir o dois pela base final desejada.

Conversão da parte fracionária

Agora, para conversão de um número fracionário ou de um número com uma parte fracionária separamos a parte inteira da fracionária. Enquanto para a parte inteira realizamos o procedimento acima explicado; utilizando o método das divisões sucessivas. Para o número fracionário ou parte fracionária realizamos multiplicações sucessivas, da parte fracionária, até que o resultado seja apenas inteiros. Ou que repitam, que é quando estaremos diante de uma dizima periódica.

Por exemplo, converter o número 42,75 na base 10 para a base 2:

A parte inteira do número já foi feito acima, então descartar-se repetir os mesmo cálculos. Aqui é interessante apenas a parte fracionária.

0,75 * 2 = 1,5

0,50 * 2 = 1

Nesse caso, diferentemente do que fazemos com a parte inteira, vamos posicionando a parte inteira resultante da multiplicação na ordem que foram calculados, ou encontrados.

No nosso exemplo, tivemos como resultado 11.

Desse modo, o 42,75 na base 10 para a base 2 é: 101010,11.

Conversão das demais bases para decimal

Para convertemos um número em determinada base para decimal, basta aplicar a definição do que vimos quando escrevi sobre ***********************bases numéricas*********************** linhas acima.

Relembrando. Para conseguir o valor do número, na base dez, a partir de determinada base fazemos o seguinte.

Multiplicamos os dígitos pela base elevada a sua posição. Quando número for fracionário, ou parte fracionária, a posição é negativa. Após somamos os produtos e teremos a representação do número na base dez.

Algoritmo:

$$
d_n⋅b^n+d_{n-1}⋅b^{n-1}+\cdots+d_0⋅b^0+d_{-1}⋅b^{-1}+d_{-2}⋅b^{-2}+\cdots
$$

Exemplo para: 101010,11.

$$
\small
x = (101010,11)_2 \newline
x = (1*2^5)+(0*2^4)+(1*2^3)+(0*2^2)+(1*2^1)+(0*2^0)+(1*2^{-1}))+(1*2^{-2}) \newline
x = 32+0+8+0+2+0+0,5+0,25
x = 42,75
$$

Prática de programação. Conversão de bases numéricas

De uma base n para a base decimal

Agora vou trazer um exemplo de um código que converte um número em determinada base para decimal na linguagem C.

#include <stdio.h>

int  value_of(char ch);
int  base_from_to_decimal(char *nbr, int base_from);

int   main(void) {

  printf("42 to b10 = %d\n", base_from_to_decimal("42", 10));
  printf("2A to b10 = %d\n", base_from_to_decimal("2A", 16));
  printf("101010 to b10 = %d\n", base_from_to_decimal("101010", 2));
  printf("\n");

  return (0);
}

int   value_of(char ch) {
  if (ch >= '0' && ch <= '9')
    return (ch - '0');
  else if (ch >= 'a' && ch <= 'f')
    return (ch - 'a' + 10);
  else if (ch >= 'A' && ch <= 'F')
    return (ch - 'A' + 10);

  return (0);
}

int  base_from_to_decimal(char *nbr, int base_from)
{
  int   result;

  result = 0;
  while(*nbr)
    {
        result = result * base_from + value_of(*nbr);
        nbr++;
    }

  return (result);
}
Enter fullscreen mode Exit fullscreen mode

O que interessa no código acima são as funções value_of e base_from_to_decimal.

A função value_of devolve o inteiro correspondente ao um caractere na tabela ASCII (American Standard Code for Information Interchange ou ”Código Padrão Americano para o Intercâmbio de Informação”).

Esse processo de recuperação é necessário pelo fato que a número a ser convertido é passado para a função base_from_to_decimal como uma cadeia de caracteres, mais comumente conhecido: uma string.

A função base_from_to_decimal recebe dois parâmetros: a cadeia de caracteres que contém a representação do número a ser convertido para decimal e um inteiro indicando qual base ela está organizado.

No corpo, declaramos e é inicializado uma variável, result, do tipo inteiro, que será retornada com o valor do número convertido de decimal.

Em seguida realizamos uma interação sobre a ***string*** recebida. Para cada caractere recuperemos o seu valor decimal da tabela ASCII com a função value_of. Esse valor é somado ao produto do valor de result, a cada interação, multiplicado pela base de origem.

Uma vez encerrado o *loop* a variável result é retornada com a representação do número na base dez.

O código é uma implementação bem grosseira. Apenas como demonstração do conceito aqui estudado. Observar-se que esse código realiza apenas conversão de números inteiros.

Da base decimal para uma base n

O código abaixo converte um número decimal para uma outra base desejada.

#include <stdio.h>
#define MAX_SIZE 32

void    to_base(int nbr, char *base, int len, char resulted[], int i)
{
    if (nbr/len != 0)
        to_base((nbr/len), base, 2, resulted, i);

    while (resulted[i] != '\0'&& i < MAX_SIZE)
        i++;

    resulted[i] = base[nbr%len];
}

int main(void) 
{
  char resulted[MAX_SIZE];
  int  nbr;
  int  i;

  nbr = 42;
  i= 0;
  if (nbr < 0)
  {
    sing++;
    resulted[0] = '-';
  }
  to_base(nbr, "01", 2, resulted, i);
  printf("%d to B2: %s\n", nbr, resulted);
  return (0);
}
Enter fullscreen mode Exit fullscreen mode

Explicando rapidamente a função main.

Nela é declarada um vetor de caracteres no qual será armazenado a representação do nosso número convertido. Em seguida é declarado a variável nbr , tipo inteiro, que será utilizada para definir o número que se deseja converter e o inteiro i que terá a função de definir o início do posicionamento dos caracteres. Pois, caso o número seja negativo, será necessário posicionar o sinal negativo no início do vetor.

Logo, é feito um verificação se o número é negativo, se sim é realizado o procedimento descrito acima.

Feito isso, é realizada uma chamada para a função to_base que recebe cinco argumentos:

  1. O número a ser convertido, do tipo inteiro: nbr;
  2. A base desejada, do tipo cadeia de caracteres: base;
  3. O tamanho da base, do tipo inteiro: len;
  4. Um vetor de caracteres onde será salvo a representação numérica convertida: resulted;
  5. E um inteiro, que serve com index para o o vetor: i.

A função to_base é recursiva. Ela chama a se mesma por quanto o valor de nbr for diferente de zero. E a cada nova chamada o valor de nbré dividido por len. Lembrando que, a cada nova chamada da função, ela é empilhada na pilha com os valores atuais da chamada. Aqui não vou entrar nos detalhes de como é a execução de uma função recursiva.

Quando o resultado da divisão for zero as chamadas recursivas se encerram e volta a continuar o fluxo de execução, da função, a partir de cada chamada.

Outro ponto importante a lembrar: é que devemos alinhar os restos da divisão na ordem inversa que forem encontrados. Nesse caso, devemos salvar o resto da cada divisão a partir do resultado da última chamada da função até a primeira. Enquanto é desempilhada da pilha de chamadas.

Continuando a explicação da função.

No laço while seguinte, recortado do código da função to_base :

while (resulted[i] != '\0' && i < MAX_SIZE)
        i++;
Enter fullscreen mode Exit fullscreen mode

O valor de i que é incrementado até que seja encontrado um local no vetor resulted que possa receber o dígito, desde que seja respeitado o tamanho máximo disponível pelo vetor.

Em seguida, o valor do digito resultante do módulo do valor presente de nbr por len é armazenado na vetor que representará o número convertido ao final. A posição é dada pelo valor de i.

Imperar anotar que nos dois exemplos não é implementado uma forma de lidar com números fracionários, mas caso o leitor tenha interesse: Neste artigo o autor implementa um algoritmo que converte um número de ponto flutuante para uma ***string*** que representa o número na base 2.

Latest comments (0)