Usuários online

sexta-feira, 11 de novembro de 2011

Introdução a Algoritmos - Aula 11/11/2011 (Gerador de Valores por Extenso - Melhorias)

Gerador de Valores por Extenso - Melhorado

No gerador de valores por extenso anterior, ele só trabalhava com valores inteiros na faixa de 0 a 999. Nesta melhoria proposta, além de trabalhar com valores monetários, a faixa foi passada de inteiro para ponto decimal, assim podemos trabalhar com valores desde R$ 0,00 até R$ 999,99 reais. Além disso, foram corrigidos alguns erros de lógica encontrados no programa anterior. O erro de centenas inteiras, como 200, 300, ..., 900 foi corrigido (destacado em vermelho no código abaixo). Diversos comentários explicativos foram acrescidos ao código, para melhor entendimento.

Como esse é um programa didático, ele não tem muita precisão, já que usa o tipo double para o valor monetário e algumas operações aritméticas a fim de separar os valores da parte inteira e da parte centesimal. Infelizmente, por um problema de arredondamento e de precisão dos tipos float e double, às vezes o valor dos centavos fica diminuído de 1 centavo. Entretanto, volto a frisar, este é um programa didático e não profissional.  Nossa intenção é mostrar ao visitante o que o C/C++ pode fazer.

OBSERVAÇÃO
Não copie, cole e execute simplesmente o código. Procure executá-lo, testá-lo e ver o que ele pode fazer. Depois, tente ler o código e acompanhar o algoritmo, juntamente com os comentários, pois assim você poderá entender a lógica por trás da execução. Isso é de suma importância para o aprendizado de C/C++, bem como de qualquer linguagem de computador.



#include <cstdlib>
#include <iostream>

using namespace std;

char* extenso(int);

int main(int argc, char *argv[])
{
    double n;
    int v_reais;
    int v_centavos;

    printf("Forneca um numero entre 0 e 999.99: ");
    scanf("%lf", &n);

    // separamos o valor lido em reais e centavos
    v_reais = (int) n;
    v_centavos = (int) (n * 100) % 100;
   
    printf("%d \'real(is)\' %d \'centavo(s)\'\n\n", v_reais, v_centavos);
   
    // geramos o valor por extenso
    if(v_reais>0)
        printf("%s", extenso(v_reais));
    if(v_reais>1)
        printf(" reais");
    else
    if(v_reais==1) printf(" real");
    if((v_centavos>0) && (v_reais>0))
        printf(" e %s", extenso(v_centavos));
    else
    if(v_centavos>0)
        printf("%s", extenso(v_centavos));
    if(v_centavos>1)
        printf(" centavos");
    else
    if(v_centavos==1) printf(" centavo");
    printf("\n\n");
   
    //for(n=0;n<=999;n++) printf("%s  ", extenso(n));
   
    system("PAUSE");
    return EXIT_SUCCESS;
}

char* extenso(int num) {
    char *unidades[10] = {
        "", "um", "dois", "tres", "quatro", "cinco", "seis", "sete", "oito",
        "nove"
    };
   
    char *dezenas[19] = {
        "", "dez", "vinte", "trinta", "quarenta", "cinquenta", "sessenta",
        "setenta", "oitenta", "noventa", "onze", "doze", "treze", "quatorze",
        "quinze", "dezesseis", "dezessete", "dezoito", "dezenove"
    };
   
    char *centenas[10] = {
        "", "cento", "duzentos", "trezentos", "quatrocentos", "quinhentos",
        "seiscentos", "setecentos", "oitocentos", "novecentos"
    };
   
    char* s;
    int u, d, c;
   
    s = (char *) calloc(200, sizeof(char));
   
    strcpy(s, ""); // variável inicia vazia
   
    u = num % 10; // unidade
    num = (num - u) / 10;
    d = num % 10; // dezena
    c = (num - d) / 10; // centena
   
    if((c == 1) && (d == 0) && (u == 0)) { // caso especial: valor igual a 100
        strcat(s, "cem"); // caso especial
        return s;
    }
    else
    if((c >= 1) && ((d != 0) || (u != 0))) { // valores entre 101 e 999
        strcat(s, centenas[c]);
        if(d > 0) strcat(s, " e ");
        strcat(s, dezenas[d]);
        if(u > 0) strcat(s, " e ");
        strcat(s, unidades[u]);
        return s;
    }
    else
    {
        if((c == 0) && (d > 0) && (u == 0)) { // valores como 10, 20, ..., 90 etc.
            strcat(s, dezenas[d]);
            if(u > 0) {
            strcat(s, " e ");
            strcat(s, unidades[u]);
        }
        return s;
    }
    else
    if((d > 0) && (d != 1) && (u > 0)) { // valores entre 21 e 99
        strcat(s, dezenas[d]);
        strcat(s, " e ");
        strcat(s, unidades[u]);
        return s;
    }
    else 
    if((c > 0) && (d == 0) && (u == 0)) { // caso especial: centenas redondas como 500, 600 etc.
        strcat(s, centenas[c]);
        return s;
    }
    else
    if((d == 1) && (u > 0)) {
        strcat(s, dezenas[d*10 + u - 1]); // caso especial: valores entre 11 e 19
        return s;
    }
    else
    {
        strcat(s, unidades[u]); // valores entre 0 e 9
        return s;
    }
    }
}

Nenhum comentário:

Postar um comentário

Observação: somente um membro deste blog pode postar um comentário.

LinkWithin

Related Posts Plugin for WordPress, Blogger...

NOSSO OBJETIVO

OBJETIVO

Este blog será usado para divulgação de minhas ideias, notícias sobre tecnologia, disponibilização de links para download de materiais diversos (incluindo materiais didáticos -- que poderão ser usados em minhas aulas e/ou cursos). Gostaria de DEIXAR BEM CLARO que quaisquer materiais disponibilizados através deste blog são, tão somente, para acompanhamento de aulas e/ou cursos, e não constituem de modo algum, aulas na modalidade "ensino à distância" (EAD). Alunos têm total acesso aos materiais disponíveis, mas somente como tutoriais passo a passo. Apostilas disponibilizadas através deste blog não são materiais obrigatórios em disciplinas cursadas ou cursos ministrados.

RESPONSABILIDADE

O autor deste blog não é responsável pelo mau uso, intencional ou não, de qualquer código de programa disponibilizado aqui. Os códigos de programas disponíveis neste blog para download é e serão sempre, e tão somente, para uso didático durante o aprendizado. Seja bem-vindo.