Escreva (utilizando para, se, então, …) um algoritmo para conversão de um número fracionário da base dois para base dez. (sugestão: página 6 do livro da Ruggiero)

Passo 1

O que o enunciado pede e o que temos de entrada:
  • Pede um algoritmo (em pseudocódigo usando comandos como “para”, “se”, “então”, …) que converta um número fracionário dado na base dois para a base dez.
  • Entrada: uma representação em texto de um número binário com parte inteira e opcional parte fracionária, por exemplo 101{.}011 ou 1101 ou .101. Pode também ter sinal negativo, por exemplo -10{.}01.
  • Saída: um número em base dez (real) equivalente ao binário de entrada, por exemplo 5{,}375 para 101{.}011.
O enunciado não exige formato específico de saída (string, float, etc.), então assumimos que a saída será um número real em base dez com precisão suficiente ou arredondada conforme necessário.

Passo 2

Ideia matemática por trás da conversão (a “aula” rápida):
  • Cada dígito binário vale 0 ou 1.
  • À esquerda do ponto binário os pesos são potências inteiras de dois: da direita para a esquerda 2^{0},2^{1},2^{2},\dots.
  • À direita do ponto binário os pesos são potências negativas de dois: da esquerda para a direita 2^{-1},2^{-2},2^{-3},\dots.
  • Portanto, para um número binário escrito genericamente como
b_{n-1}b_{n-2}\dots b_{1}b_{0}.b_{-1}b_{-2}\dots b_{-m},
o valor em decimal é
\sum_{i=0}^{n-1} b_{i} \, 2^{i} \quad+\quad \sum_{j=1}^{m} b_{-j}\,2^{-j},
onde cada b_{k}\in\{0,1\}. (Aqui indexes positivos são contados a partir do dígito de menor ordem à esquerda do ponto.)
Exemplo concreto e didático: converter 101{.}011.
  • Parte inteira 101 = 1\cdot 2^{2} + 0\cdot 2^{1} + 1\cdot 2^{0} = 4+0+1 = 5.
  • Parte fracionária .011 = 0\cdot 2^{-1} + 1\cdot 2^{-2} + 1\cdot 2^{-3} = 0 + 0{,}25 + 0{,}125 = 0{,}375.
  • Soma = 5 + 0{,}375 = 5{,}375.

Passo 3

Método direto (fácil de entender e aplicar na prova): somar contribuições das potências de dois — algoritmo conceitual.
  • Passos principais:
    1. Separar a string binária em parte inteira e parte fracionária (ao redor do ponto).
    2. Percorrer os dígitos da parte inteira da direita para a esquerda, acumulando digit \times 2^{expoente} com expoente começando em 0 e incrementando.
    3. Percorrer os dígitos da parte fracionária da esquerda para a direita, acumulando digit \times 2^{-k} com k começando em 1 e incrementando.
  • Observação prática importante para prova: em vez de calcular 2^{i} com potência, mantenha um multiplicador que começa em 1 (para 2^{0}) e multiplica por 2 a cada passo; para a fração comece o multiplicador em 1/2 e divida por 2 a cada passo. Assim evita-se uso de função pow e fica tudo com multiplicações/divisões simples à mão.

Passo 4

Implementação passo a passo mostrando como calcular sem funções de potência (maneira “caneta e papel”):
  • Para a parte inteira:
    • Inicialize soma \leftarrow 0.
    • Inicialize peso \leftarrow 1 (que representa 2^{0}).
    • Percorra os dígitos da parte inteira do menos significativo (direita) para o mais significativo (esquerda):
      • Converta o caractere do dígito em digit\in\{0,1\}.
      • Faça soma \leftarrow soma + digit \times peso.
      • Atualize peso \leftarrow peso \times 2.
  • Para a parte fracionária:
    • Inicialize peso\_frac \leftarrow 1/2 (que representa 2^{-1}).
    • Percorra os dígitos da parte fracionária da esquerda para a direita:
      • Converta o caractere do dígito em digit\in\{0,1\}.
      • Faça soma \leftarrow soma + digit \times peso\_frac.
      • Atualize peso\_frac \leftarrow peso\_frac / 2.
  • No final, trate sinal negativo se houver.
Exemplo rápido usando essa técnica para 101{.}011:
  • Parte inteira: digits direita->esquerda 1,0,1 com pesos 1,2,4 => acrescenta 1\cdot1 + 0\cdot2 + 1\cdot4 = 5.
  • Parte fracionária: digits esquerda->direita 0,1,1 com pesos 1/2,1/4,1/8 => acrescenta 0 + 1\cdot1/4 + 1\cdot1/8 = 0{,}375.

Passo 5

Método alternativo (útil para sófrações ou quando quiser ver o processo de geração de dígitos): algoritmo “multiplica por 2” para a parte fracionária.
  • Ideia: se f é a parte fracionária em decimal (inicialmente interpretada como binário .b_{1}b_{2}\dots), então repetidamente faz-se f \leftarrow f \times 2; a parte inteira de f dá o próximo dígito binário; depois subtrai-se essa parte inteira de f e continua-se. Para conversão inversa (binário → decimal) isso serve para entender repetição infinita ou para gerar aproximações. Na prática para converter binário→decimal esse método é mais usado quando se quer converter decimal fracionário para outra base; para o nosso caso de binário→decimal a soma com pesos é mais direta. Ainda assim, é bom conhecer.
  • Limite-se a um número máximo de iterações para controlar precisão (por exemplo m dígitos da fração desejados).

Passo 6

Casos extremos, precisão e validações (coisas para a prova):
  • Se a parte fracionária for periódica (algumas frações binárias geram representação finita em binário? sim — muitas geram infinita em base dez, mas aqui a entrada já é binária), ao converter para decimal o resultado é exato se a representação binária for finita; caso a entrada seja conceito de fração com repetição, não vamos inventar repetição: usamos a string que foi dada.
  • Se a entrada contiver caracteres diferentes de ‘0’, ‘1’, ‘.’ e opcionalmente ‘-’, então detectar erro e avisar.
  • Deixar explícito quantas casas decimais de saída serão apresentadas (ou retornar o número real com precisão da linguagem).
  • Em prova sem calculadora, a técnica do multiplicador peso e peso\_frac permite somas manuais passo a passo sem potências complexas.

Passo 7

Agora sim: o pseudocódigo final (claro, usando os comandos exigidos “para, se, então, …”) — este é o algoritmo pedido que pode ser usado como resposta direta na prova. Usei notação simples e explícita; todas as variáveis matemáticas aparecem em TeX conforme pedido.

Resposta

Entrada: uma string bin\_str no formato opcionalmente com sinal, contendo dígitos ‘0’ ou ‘1’ e no máximo um ponto ‘.’ separando parte inteira e parte fracionária.
Saída: número decimal resultado.
Algoritmo:
  • sinal \leftarrow 1\n
  • i \leftarrow 1\n
  • se bin\_str[1] = '-' então\n
    sinal \leftarrow -1\n
    i \leftarrow 2\n
  • separar bin\_str[i..] em duas partes pela ‘.’; se não houver ‘.’, parte inteira int\_part \leftarrow bin\_str[i..] e parte fracionária frac\_part \leftarrow ""\n
  • soma \leftarrow 0\n
  • // converter parte inteira\n
  • peso \leftarrow 1 // representa 2^{0}\n
  • para k de comprimento( int\_part) até 1 passo -1 faça\n
    digit\_char \leftarrow int\_part[k]\n
    se digit\_char não é ‘0’ nem ‘1’ então\n
    erro: entrada inválida\n
    fim se\n
    digit \leftarrow se digit\_char='1' então 1 senão 0\n
    soma \leftarrow soma + digit \times peso\n
    peso \leftarrow peso \times 2\n
  • fim para\n
  • // converter parte fracionária\n
  • peso\_frac \leftarrow 1/2 // representa 2^{-1}\n
  • para k de 1 até comprimento( frac\_part) faça\n
    digit\_char \leftarrow frac\_part[k]\n
    se digit\_char não é ‘0’ nem ‘1’ então\n
    erro: entrada inválida\n
    fim se\n
    digit \leftarrow se digit\_char='1' então 1 senão 0\n
    soma \leftarrow soma + digit \times peso\_frac\n
    peso\_frac \leftarrow peso\_frac / 2\n
  • fim para\n
  • resultado \leftarrow sinal \times soma\n
  • retornar resultado

Exercícios relacionados