Ir ao conteúdo
  • Cadastre-se

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


Posts recomendados

 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
Link para o comentário
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
Link para o comentário
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
Link para o comentário
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
Link para o comentário
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
Link para o comentário
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
Link para o comentário
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
Link para o comentário
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
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 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...