sábado, 22 de setembro de 2012

Da base decimal para as bases binária, hexadecimal e octal

Há muito tempo já tinha reparado que não existia uma função pronta que converte da base decimal para binária.

Eu estava enganado e um professor falou da função itoa. No entanto, para minha decepção, a função não funciona apresentando o erro abaixo:

teste.c:(.text+0x4f): undefined reference to `itoa'

Como disse um velho amigo de programação: "você não precisa saber todos os comandos, funções e etecera. Se for criativo, você contorna a situação". Então criei minha própria forma de converter de decimal para binário. Basta executar o programa na linha de comando passando como parâmetro o número na base decimal. O código em C++ contém comentários descrevendo suas etapas.

Bibliotecas necessárias:

  • iostream
  • iomanip
  • cstdlib

Para converter de decimal para binário, a primeira tarefa é determinar a quantidade de divisões. Para tal, foi preciso que primeiro cálculo fosse feito fora do while para determinar o valor do quociente. Só então o loop while começa incrementando a variável divisoes.

A cada divisão, o valor do resto é armazenado em um vetor. Assim, cada cálculo, um índice é preenchido.

Para exibir o resultado, é impresso o quociente encontrado na última divisão e o vetor de restos do maior para o menor índice.

Para o valor hexadecimal, a namespace hex converte para hexadecimal. Finalmente, para o valor octal, a namespace oct converte para octal.

Apresento o código-fonte abaixo.


// Created by Murilo Fujita <murilofujita@gmail.com> in 09/21/2012

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <iomanip>
using std::setprecision;
using std::setw;
#include <cstdlib>
using std::hex;
using std::oct;

int main(int argc, char** argv) {

    int pos=50; //quantidade de POSICOES do array
    int num,quo,res[pos], divisoes, numero;

    if (argc <2)
    {
      cout << "Digite um número na base decimal" << endl;
      exit(1);
    }

    num=atoi(argv[1]);

    numero=num; // num é usado para calculos; numero é usado para recuperar o input
    divisoes=0; // inicializa a quantidade de divisoes

    quo=num/2;
    res[0]=num%2; // precisa calcular o primeiro resto para o WHILE saber como comeca

    pos=1; // comeca em 1 porque o indice 0 ja foi calculado fora do loop
    while (quo>1)
    {
        quo=num/2; // quociente
        res[pos++]=num%2; // armezena os restos
        num=quo; // sacada para realizar as divisoes sucessivas
        divisoes++; //conta a quantidade de divisoes
    }
    cout << numero << " precisa de " << divisoes+1 << " bits." << endl;

    pos=divisoes;
    cout << "binário: ";
    cout << quo; // imprime o bit mais significativo: o quociente da ultima divisao
    for (int j=divisoes; j>0; j--)
    {
       cout << res[pos--]; // imprime os restos do ultimo indice para o primeiro
    }

    cout << endl;
    cout << "hexadecimal: " << hex << numero << endl;
    cout << "octal: " <<  oct << numero << endl;
    return 0;
}

E para concluir, dois exemplos da resposta do programa:

./bases_numericas.out 51966
51966 precisa de 16 bits.
binário: 1100101011111110
hexadecimal: cafe
octal: 145376

./bases_numericas.out 987654321
987654321 precisa de 30 bits.
binário: 111010110111100110100010110001
hexadecimal: 3ade68b1
octal: 7267464261

quinta-feira, 6 de setembro de 2012

Script para organizar a conjugação de verbos

Procurando ajudar uma colega taiwanesa que está se adaptando à nossa língua-pátria, eu respondo os e-mails mostrando a conjugação dos verbos para que ela entenda a concondância do pronome com a flexão do verbo.

Antes é necessário instalar o pacote brazilian-conjugate. O aplicativo apt-get instala o pacote através da linha de comando:

$ apt-get install brazilian-conjugate

Uma vez instalado, para chamar o aplicativo, digite:

$ conjugue

A figura abaixo mostra a tela assim que o programa inicia e em destaque vemos o comando que executa o conjugue bem como o verbo escolhido para ser conjugado (extorquir).


Figura 1. Tela Inicial do conjugue

Esta outra figura mostra a conjugação. Perceba que o programa reconhece os verbos defectivos e omite em certos pronomes.


Figura 2. Selecionando os tempos verbais

Note que o texto selecionado será copiado para área de memória e será usado como entrada para o script a seguir.

#!/bin/bash
# Created in September/02/2012

if [ "$#" -eq 0 ]
  then
    echo Falta o parâmetro dos verbos
  else
    conj1=`echo $1 | tr ":" " " | cut -f1 -d" "`
    conj3=`echo $1 | tr ":" " " | cut -f3 -d" "`
    conj4=`echo $1 | tr ":" " " | cut -f4 -d" "`
    conj6=`echo $1 | tr ":" " " | cut -f6 -d" "`

    echo eu $conj1
    echo ele/você $conj3
    echo nós $conj4
    echo eles/vocês $conj6
fi

Primeiro o script verifica se recebeu uma entrada ao ser chamado na linha de comando. Caso sim, as variáveis conj1, conj2, conj4 e conj6 associarão às flexões dos pronomes eu, ele, nós, eles respectivamente. Em seguida o echo imprime o pronome juntamente com o verbo flexionado. Como exemplo, vamos ver a saída do verbo extorquir no presente do indicativo:

./conjugador.sh :extorques:extorque:extorquimos:extorquis:extorquem
eu
ele/você extorque
nós extorquimos
eles/vocês extorquem

Repare que o script separa as flexões identificando o sinal de dois pontos (:). Assim, foram recebidos 5 parâmetros e reconhecido que não existe a primeira flexão.

Conclusão: Além de agilizar na orientação de como escrever corretamente, pode ser uma ferramenta de grande utilidade para evitar deslizes na língua portuguesa.