Ir ao conteúdo
  • Cadastre-se

programa em C


Karpov1

Posts recomendados

Vamos analisar o problema:

 

Vamos começar pelos casos básicos: Se número = 0 apenas imprime 0 independentemente do valor de e. Se o número for diferente de zero, por exemplo quando número = 543210, mas a potência e for igual a zero (e=0), apenas imprime o próprio número, nesse caso 543210. Mas senão forem iguais a zero precisamos considerar os outros casos...

 

Quando e é diferente de 0, existem dois casos diferentes:

1 - A vírgula fica no meio do número - Exs: 543210*10^-3 = 543,210 e 543210*10^-1 = 54321,0

2 - A vírgula fica antes do número - Ex: 543210*10^-8 = 0,00543210

 

Primeiro precisamos detectar de qual dos 2 casos se trata, para isso podemos usar uma divisão, pois 543210*10^-e = 543210 / (10^e). Portanto teremos o primeiro caso quando fizermos a divisão inteira e o resultado for não nulo (diferente de zero), por exemplo 543210 dividido inteiramente por 10^3 dá 543 (com resto 210). E o segundo caso quando a divisão der resultado nulo (igual a zero), por exemplo 543210 dividido inteiramente por 10^8 dá 0 (com resto 543210).

 

Se se tratar do primeiro caso, basta usar a divisão inteira e o resto da divisão por 10^e, pra calcular o que vem antes e o que vem depois da vírgula, por exemplo quando e = 1 o resultado destas duas operações serão 54321 e 0, respectivamente. Então apenas imprimimos os 2 resultados separados por uma vírgula.

 

No entanto, se se tratar do segundo caso, fica um pouco mais complexo, pois precisamos determinar quantos zeros deverão ser impressos antes de imprimirmos o número... Neste caso como a divisão deu 0, já podemos assumir que o número começa com "0," e imediatamente imprimir isso na tela. Então precisamos ir fazendo testes consecutivos de divisões com potências menores (ir decrementando a potência em 1 unidade), e imprimir um novo zero no prompt toda vez que a divisão inteira der resultado zero. E quando a divisão for diferente de zero podemos imprimir o número. Para entender melhor veja este exemplo:

Assumindo: número=543210 e e=8:543210 / (10^8) = 0-> logo imprimimos "0," | Prompt> 0,Agora precisamos testar com potências menores:543210 / (10^7) = 0-> imprime um novo "0" | Prompt> 0,0543210 / (10^6) = 0-> imprime um novo "0" | Prompt> 0,00543210 / (10^5) = 5-> como o resultado é não nulo já podemos imprimir o número "543210" | Prompt> 0,00543210

Obs: Como pode observar será necessário calcular várias potências de 10, portanto eu sugiro que implemente uma função que calcule estas potências, para usá-las nas operações do programa.

Link para o comentário
Compartilhar em outros sites

Acho mais fácil postar o código do que ficar explicando.

Corrigi o bug e agora acho que está ok

#include <stdio.h>#include <stdlib.h>int main(){    int n, e, decimal = 0, d = 1, zeros = 0;    printf("n: ");    scanf("%d", &n);    printf("e: ");    scanf("%d", &e);    if(!e){        printf("%d\n", n);        exit(0);    }    while(e--){        decimal += (n % 10) * d;        d *= 10;        if(!(n % 10))             zeros++;        else            zeros = 0;        n /= 10;    }        if(!decimal) zeros--;    printf("%d.", n);    while(zeros--) printf("0");    printf("%d\n", decimal);    return 0;}

Só dividir sucessivamente por 10 e ir contando essas passadas. Quando o resultado da divisão der 0, é hora de deixar o laço.

[ ]'s

LNW

Ah, sim. Achei que você conhecesse mais outro método
  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Eu tenho uma duvida "while(e--){"  que você escreveu...isso significa que enquanto e = e -1 algo vai acontecer. então, por exemplo, se o expoente for 5, você vai substituir o 5 por 4 e fazer algo, dai você vai substituir o 4 por 3 e fazer outra coisa, dai vai indo...nunca vai acabar esse while...nao entendi ....

Link para o comentário
Compartilhar em outros sites

Em C valores inteiros não nulos resultam em True/Verdadeiro, e zero é tido como False/Falso, quando avaliados como booleanos...

 

Portanto "while(e--)" vai ficar rodando enquanto "e--" for diferente de 0 (pois é avaliado como True), e sai quando chegar a 0 (ou seja, se torna False).

 

Logo isto seria o mesmo que: "for (e; e != 0; e--){"

 

(Sabendo dessa propriedade observe que if(e != 0) é o mesmo que if(e), logo para expressão acima também poderíamos escrever "for (e; e; e--){".)

Link para o comentário
Compartilhar em outros sites

Eu entendi o programa que ele escreveu até antes do primeiro while, depois eu nao entendi...Vamos por partes:

 while(e--){
        decimal += (n % 10) * d;
        d *= 10;
O que ele quis dizer com essas duas frases?
        if(!(n % 10)) 
            zeros++;
        else
            zeros = 0;
 
        n /= 10;
    }
    Aqui ele quis dizer que se o resto de n por 10 for diferente de zero, a gente vai acrescentar um zero no numero, senão a gente nao vai acrescentar zeros e vamos substituir n pelo quociente de n por 10?
    if(!decimal) zeros--;
 
    printf("%d.", n);
    while(zeros--) printf("0");
    printf("%d\n", decimal);
Aqui eu nao entendi nada....
    return 0;
}
Link para o comentário
Compartilhar em outros sites

Em C a exclamação "!" é um operador de inversão booleana, ou seja !(true) é igual a false. Portanto se "if(a)" é igual a "if(a!=0)", então temos que "if(!a)" será o mesmo que if(a==0).

        decimal += (n % 10) * d; //        d *= 10;

O operador de atribuição "+=" soma o que vier depois dele ao valor atual da variável (ou seja, a+=b é igual a a=a+b ),

E o operador de atribuição "*=" multiplica o que vier depois dele ao valor atual da variável (ou seja, a*=b é igual a a=a*b ),

(Aí fica lógico deduzir o que o operador "/=" faz.)

 

Portanto, aí ele está fazendo com que o n % 10 (resto da divisão de n por 10) seja multiplicado por um multiplicador "d", e somado ao valor atual de "decimal" a cada execução do ciclo while. E esse multiplicador "d" é iniciado com valor 1 e vai sendo multiplicado por 10 a cada clclo, tal que no próximo ciclo o valor somado a "decimal" será deslocado em 1 casa para a esquerda.

 

E no fim do ciclo tem um:

        n /= 10;

Então, o que ele está fazendo a cada ciclo é obter o último digito do número (resto da divisão por 10), multiplica por um fator multiplicador de posicionamento (d), e soma aos decimais, e no fim do ciclo elimina o último digito do número n (divide por 10).

 

Assim teremos que a cada ciclo o programa vai separando do valor original a parte decimal:

Ex:-Inicialmenten=543210decimal=0-Então a cada ciclo o programa seguirá fazendo:n=54321decimal=0n=5432decimal=10n=543decimal=210etcAté quando? Depende do valor de e, que é o que diz onde a vírgula deve ficar, e por isso é o que define quando o ciclo acaba...

O problema aparece quando o número não tem casas suficientes, por exemplo quando n=543210 e e=8, pois, neste exemplo, a partir do sexto ciclo n e decimal ficam fixos com valores n=0 e decimal=543210.

A solução do oliver para isto foi usar um contador ("zeros"), para contar quantas vezes o ciclo permanece nessa condição, e assim contar quantos zeros deverão ser adicionados ao número quando for imprimi-lo.

Ou seja, ele checa se o valor do resto da divisão de n por 10 é igual a zero ( "if(!(n % 10))" ), se sim ele inicia a contagem de zeros.

Mas note que se o número original n tiver dígitos 0 no meio, como no nosso exemplo 543210, haverão ocorrências em que resto da divisão será zero, e a contagem do número de zeros será iniciada no momento indevido, para compensar isso ele faz o programa resetar o valor do contador de zeros para o valor inicial 0, se num dos próximos ciclos o resto da divisão (n%10) der algo diferente de zero ("else zeros = 0;").

 

Entretanto a contagem de zeros também é usada para verificar zeros consecutivos no meio do número, como por exemplo quando n=10000 e e=3, o resultado esperado seria "10,000", mas nesse caso teríamos n=10 e decimal=0 ao fim do ciclo, então sem a contagem de zeros o programa imprimiria "10,0". Mas com o contador, "zeros" nesse caso teria valor 3 ao fim do ciclo, e se o programa imprimisse 3 zeros extras o resultado seria "10,0000", para compensar isto ele decrementa em 1 o valor do contador se a variável "decimal" for igual a zero, para obter o resultado esperado "10,000"...

Link para o comentário
Compartilhar em outros sites

Observando o código do oliver vi que haveriam falhas na minha analise original, visto que números com 0 no meio retornariam respostas erradas seguindo aquela lógica (ex: n=1000023 e e=4 geraria resultado "100,23").

 

Aqui está a lógica revisada:

se e for nulo:  imprime nsenao:  imprime n / (10^e) e ","  resto = n % (10^e)  para potencia indo de e-1 até 0 com decremento 1:    imprime resto / (10^potencia)    resto = resto % (10^potencia)  fim do parafim do se

Exs:

n=210e=5n / 10^e = 210 / 10^5 =  0 | Prompt> 0,resto = 210 % 10^5 = 210potencia = e-1 = 4resto / 10^potencia = 210 / 10^4 = 0 | Prompt> 0,0resto = 210 % 10^4 = 210potencia = 3resto / 10^potencia = 210 / 10^3 = 0 | Prompt> 0,00resto = 210 % 10^3 = 210potencia = 2resto / 10^potencia = 210 / 10^2 = 2 | Prompt> 0,002resto = 210 % 10^2 = 10potencia = 1resto / 10^potencia = 10 / 10^1 = 1 | Prompt> 0,0021resto = 10 % 10^1 = 0potencia = 0resto / 10^potencia = 0 / 10^0 = 0 | Prompt> 0,00210resto = 0 % 10^0 = 0
n=10045e=3n / 10^e = 10045 / 10^3 =  10 | Prompt> 10,resto = 10045 % 10^3 = 45potencia = e-1 = 2resto / 10^potencia = 45 / 10^2 = 0 | Prompt> 10,0resto = 45 % 10^2 = 45potencia = 1resto / 10^potencia = 45 / 10^1 = 4 | Prompt> 10,04resto = 45 % 10^1 = 5potencia = 0resto / 10^potencia = 5 / 10^0 = 5 | Prompt> 10,045resto = 5 % 10^0 = 0
Link para o comentário
Compartilhar em outros sites

Isrnick, eu tentei fazer o programa seguindo o raciocinio que você montou nessa tabela, mas tá dando errado...fiz assim:

#include <stdio.h>
#include <stdlib.h>
 
int main(){
    int n, e, resto;
 
    printf("n: ");
    scanf("%d", &n);
    printf("e: ");
    scanf("%d", &e);
 
    if(!e){
        printf("%d\n", n);
        exit(0);
 
}
else {
printf ("n/(10^e)) ");
printf(",");
resto = n % (10^e);
 }
while(e--){
 
printf("resto/(10^e)");
resto = resto % (10^e);
}
 
    return 0;
}
 
Pode corrigir o que está errado?
Link para o comentário
Compartilhar em outros sites

Para quem quiser outra alternativa, fiz um código mais fácil de entender, segue.

#include <stdio.h>int main(){    int n, e, decimal, d, zeros, i;    printf("n: ");    scanf("%d", &n);    printf("e: ");    scanf("%d", &e);    if(e == 0){        printf("%d\n", n);    }else{        decimal = 0;        d = 1;        zeros = 0;        for(i = e; i > 0; i = i - 1){            decimal = decimal + (n % 10) * d;            d = d * 10;            if((n % 10) == 0){                zeros = zeros + 1;            }else{                zeros = 0;            }            n = n / 10;        }        if(decimal == 0){            zeros = zeros - 1;        }        printf("%d.", n);                for(i = zeros; i > 0; i = i - 1){            printf("0");        }        printf("%d\n", decimal);    }            return 0;}
Link para o comentário
Compartilhar em outros sites

 

Isrnick, eu tentei fazer o programa seguindo o raciocinio que você montou nessa tabela, mas tá dando errado...fiz assim:

#include <stdio.h>
#include <stdlib.h>
 
int main(){
    int n, e, resto;
 
    printf("n: ");
    scanf("%d", &n);
    printf("e: ");
    scanf("%d", &e);
 
    if(!e){
        printf("%d\n", n);
        exit(0);
 
}
else {
printf ("n/(10^e)) ");
printf(",");
resto = n % (10^e);
 }
while(e--){
 
printf("resto/(10^e)");
resto = resto % (10^e);
}
 
    return 0;
}
 
Pode corrigir o que está errado?

 

 

 

Não existe 10^e em C, você precisa calcular essas potências usando um ciclo...

E o comando de impressão printf está sendo usado de modo errado... Ele recebe uma string, e opcionalmente valores separados por vírgula. E a string pode conter caracteres de controle que indicam como formatar os valores separados por vírgula fornecidos (%d para números inteiros, %c para caracter, etc). Ex: printf("abcde %d %d 1234", 1000, 50) imprimirá 'abcde 1000 50 1234" no prompt...

 

 

Ok, aqui está uma solução, só não me responsabilizo por plágios...

#include <stdio.h>#include <stdlib.h>int main(){    int n, e, i, resto, pot10;    printf("n: ");    scanf("%d", &n);    printf("e: ");    scanf("%d", &e);    if(e == 0){        printf("%d\n", n);    } else {        pot10 = 1;        for(i=1; i<=e; i++)          pot10 = pot10 * 10;          //10^e        printf("%d,", n/pot10);        //Observe o uso correto de printf        resto = n%pot10;        for(i = e-1; i >= 0; i--){            pot10 = pot10/10;          //Vai dividindo por 10 pra calcular as potências menores            printf("%d", resto/pot10);            resto = resto % pot10;        }        printf("\n");    }    return 0;}
  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Exatamente, o valor máximo para "e" seria 9, pois a partir de 10 a potência "10^e" fica muito grande (10^10) para ser armazenada numa variável do tipo "int", como a variável "pot10" usada no meu código.

 

Mas é possível usar o tipo "long" (inteiro longo) ao invés de "int", que aumentaria o valor máximo de "e" para 18.

 

Ou até testar os tipos "unsigned long", "long long" ou "unsigned long long", dependendo do compilador, para aumentar ainda mais o limite, mas eu acho que para esse exercício se 9 não for suficiente, eu imagino que "e" com valores indo até 18, usando "long", já atenderia a expectativa.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!