Ir ao conteúdo
  • Cadastre-se
Gnomo Psicodélico

C Acrescentando 1 para uma alíquota e pra outra não

Recommended Posts

 Fiz esse programa pra calcular... só que ele da uma alíquota de 0,0901 (o certo seria 0,900 isso para o calculo 1, tanto que o mesmo calculo na calculadora da esse valor), já para o calculo 2 ele da a alíquota certa, alguém ta vendo algo errado para o código estar adicionando esse 01 no final ?

Calculo 1: 1.331.108,20 * 10,70% - 22.500,00 / 1.331.108,20 = 0,0900

Calculo 2: 200.000,00 * 7,3% - 5.940,00 / 200.000,00 = 0,0433

setlocale(LC_ALL, "Portuguese");
					for(int ap = 0; ap < 100; ap++)
					{
					SendMessage(gResultado,LB_DELETESTRING,0,0);	
					}
					char DozeMeses[300];
					char AliqSimp[300];
					char Iss[300];
					char Mes[300];
					char res[300];
					char AliqISS[300];
					char Desconto[300];
					double calc;
					double doze;
					double aliqsimp;
					double desconto;
					double mes;
					double iss;
					GetWindowText(gDozeMeses,DozeMeses,FIELD_LENGTH);
					GetWindowText(gAliqSimp,AliqSimp,FIELD_LENGTH);
					GetWindowText(gDesconto,Desconto,FIELD_LENGTH);
					GetWindowText(gAliqISS,AliqISS,FIELD_LENGTH);
					GetWindowText(gMes,Mes,FIELD_LENGTH);
					doze = atof(DozeMeses);    			 
					aliqsimp = atof(AliqSimp);
					iss = atof(AliqISS);		
					desconto = atof(Desconto);
					mes = atof(Mes);
					aliqsimp = aliqsimp / 100;
					calc = doze * aliqsimp;
					calc = calc - desconto;
					calc = calc / doze; 
					sprintf(res, "%.4f", calc);
					
					/*calc = atof(res);
					iss = iss * calc;
					calc = mes * calc;
					sprintf(res, "%.2f", calc);
					sprintf(Iss,"%.2f",iss);*/
					SendMessage(gResultado,LB_ADDSTRING,0,(LPARAM)res);

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

Isso depende da precisão da variável real.

26 minutos atrás, Gnomo Psicodélico disse:

Calculo 1: 1.331.108,20 * 10,70% - 22.500,00 / 1.331.108,20 = 0,0900

Seu resultado é: 0.0900967910797935

 

 

Veja que existe vários '9s' perigando o arrendondamento: 0.0900967910797935

Daí a precisão da variável ser tão importante no caso. 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
38 minutos atrás, Gnomo Psicodélico disse:

O que me recomenda fazer nesse caso então?

#include <stdio.h>  // printf
#include <stdlib.h> // EXIT_SUCCESS



/* Principal função do Programa
    Retorna
    -------
*/      int
main( void )
{
    double real = 0;
    /* Declara variável real do tipo double */


    real = (1331108.20 * 10.70/100 - 22500.00)/1331108.20;
    /* Versão C' do cálculo */

    printf( "REAL: =  %.6f \n", real ); //
    printf( "REAL: =  %.4f \n", real ); //
    /* O "problema" acontece apenas na apresentação dos dados, para qual
       exigiu-se arredondamento, floor.

       Recomenda-se não reduzir para menos de 6 dígitos de precisão.
    */
    
    return EXIT_SUCCESS;
    /* Finaliza o programa */
}

 

Boa Sorte

~~/~~

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@AnsiC  Nesse caso eu teria que definir no double os valores como você fez no exemplo a cima? se for não adianta pra mim, estou colocando os valores e preciso que ele faça o calculo pelos valores que eu colocar.

  Eu preciso de uma forma pra mostrar somente 4 digitos depois do "." sem esse problema, mas não me vem nada na mente de como eu posso resolver isso.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não existe problema, ele arredondou o número quando você exibe apenas até aquela casa. O número na variável não mudou.

 

Mas se quiser que ele arredonde para baixo vai ter que mudar o modo de arredondamento usando fesetround() da biblioteca fenv.h.

 

Função: http://en.cppreference.com/w/c/numeric/fenv/feround

Modos de arredondamento: http://en.cppreference.com/w/c/numeric/fenv/FE_round

 

Exemplo:

#include <stdio.h>
#include <fenv.h>

int main()
{
    double real;    
    
    real = (1331108.20 * 10.70/100 - 22500.00)/1331108.20;
    
    printf("%.22lf | %.4lf\n", real, real);
    
    fesetround(FE_DOWNWARD);
    printf("%.22lf | %.4lf\n", real, real);
    
    return 0;
}

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
14 minutos atrás, Gnomo Psicodélico disse:

Só uma obs, esse exemplo que você passou era pra mudar algo? porque deu a mesma coisa 0.0901

 

Era sim:

 

image.png.dda9cebd8ba6f7ba877fdf76423ed999.png

 

 

Mas pelo jeito não funcionou no GCC do Windows:

 

image.png.8e791101d2c8ddacab3e1f5f4d5e186d.png

 

:tw_dissapointed:

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá@Gnomo Psicodélico

 

4 horas atrás, Gnomo Psicodélico disse:

Nesse caso eu teria que definir no double os valores como você fez no exemplo a cima? se for não adianta pra mim, estou colocando os valores e preciso que ele faça o calculo pelos valores que eu colocar.

 

Não, é apenas um modelo que crie para realizar o teste.

 

 

4 horas atrás, Gnomo Psicodélico disse:

  Eu preciso de uma forma pra mostrar somente 4 digitos depois do "." sem esse problema, mas não me vem nada na mente de como eu posso resolver isso.

#include <stdio.h>
#include <stdlib.h> // EXIT_SUCCESS
#include <string.h> // strchr()


/* Principal função do Programa
    Retorna
    -------
*/      int
main( void )
{
    unsigned char real_str[18]; 
    unsigned char * s;
    double real;
    /* Declaração de Variáveis */


    real = (1331108.20 * 10.70/100 - 22500.00)/1331108.20;
    /* Não queremos apresentar esse valor redondo */

    sprintf( real_str, "%f", real );
    /* 1º Salvamos o resultado na :real_str: string 
       sprintf converte o valor real para string */

    s = strchr( real_str, '.' );
    /* 2º Localizamos o dot (.) e armazenamos a posição no :s: pointer 
       strchr vai retorna o ponteiro da primeira ocorrência de dot (.)
       só exite uma e armazenamos sua posição em s */

    printf( "%.*s", (int)(s - real_str)+5, real_str );
    /* Enfim, escrevemos no prompt

       Nota
       ----
       A opereção: (int)(s - real_str)+5 se resume em aritmética de ponteiros
       onde :s: é um posição númericamente maior que :real_str: tal que a di-
       ferença deles é o número de casas decimais antes de dot (.) */

    return EXIT_SUCCESS;
    /* Finaliza o programa */
}

O que achou dessa solução, (Pensei nela agora e :tw_heart:)?

 

3 horas atrás, isrnick disse:

Não existe problema, ele arredondou o número quando você exibe apenas até aquela casa. O número na variável não mudou.

Foi o que eu disse:

5 horas atrás, AnsiC disse:

O "problema" acontece apenas na apresentação dos dados, para qual exigiu-se arredondamento

 

 

 

 

Boa Sorte

~~/~~

  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se for pra "dar um jeitinho" dá pra fazer essa também:

 

#include <stdio.h>
#include <math.h>

int main()
{
    double real;
    
    real = (1331108.20 * 10.70/100 - 22500.00)/1331108.20;
    
    printf("%.4lf\n", floor(real * 1E4) * 1E-4);
    
    return 0;
}

Multiplicar por 104 pra mover a vírgula pra direita 4 casas, obtém o floor (maior número inteiro que ainda seja menor que o número analisado) do resultado, aí multiplica por 10-4 pra voltar a vírgula a posição original.

  • Obrigado 1
  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@AnsiC @isrnick  valeu, todos os 2 funcionaram :tw_heart: agora meu programa vai facilitar meu trabalho :D


@EDIT:
@AnsiC  Porque quando eu passo pra interface da errado? (o calculo 2 da certo o 1 não) 
@isrnick A mesma coisa pro seu exemplo (mas ao contrário) .--.

 char * s;
 s = strchr( res, '.' );
 sprintf(res, "%.*s",(int)(s - res)+5, res );

 SendMessage(gResultado,LB_ADDSTRING,0,(LPARAM)res);

•Exemplo do AnsiC (calculo 1 da erro, 2 da certo)

image.thumb.png.678ebbdf215596f6994791a8daa92c8e.png

•Exemplo do Isrnick (calculo 2 da erro, 1 da certo)
 

calc = floor(calc * 1e4) * 1e-4;
sprintf(res, "%.4lf",calc);

SendMessage(gResultado,LB_ADDSTRING,0,(LPARAM)res);



image.thumb.png.51202693787a3afe27ed9c6ffb537e84.png  

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá !

 

Poxa!!! Só mais uma tentativa, cuja diferença, é substituir a

operação em printf por operação em vetor. Na tentativa de

resolver esse problema, que não sei descrever.

 

Online GDB: stringalizando_double

 

 

~~/~~

 

 

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
4 horas atrás, Gnomo Psicodélico disse:

Não deu, vou pensar em alguma forma aqui, mas valeu pela tentativa

Que nada, esse é um jogo que eu gosto de jogar. 

 

 

Obrigado!

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×