Ajuda com código em C - Arredondamento de valores

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Ajuda com código em C - Arredondamento de valores

Mensagem por asimoes »

Caros,

Estou precisando ajuda com um código que usamos com clipper para resolver o problema de arredondamento de valores, gostaria de converter o código em c para harbour vejam o código:

Exemplo:

Código: Selecionar todos

FUNCTION MAIN
aa := 0.00
bb := 0.00
continua = .T.
while continua
   cls
   @ 0,0 say "a" get aa picture "9999999999999999.99"
   @ 1,0 say "b" get bb picture "9999999999999999.99"
   read
   if lastkey()<>27
      cls
      ? "valores:"
      ? aa, bb
      ?
      ? "opera‡oes em clipper:"
      ? aa+bb
      ? aa-bb
      ? aa*bb
      ? aa/bb
      ? round(aa/bb,4)
      ?
      ? "opera‡oes em c:"
      ? c_sum(aa, bb)
      ? c_sub(aa, bb)
      ? c_mult(aa, bb)
      ? c_div(aa, bb)
      ?
      ? "tecle qualquer tecla para continuar..."
      inkey(0)
   else
      continua = .F.
   endif
end
return

Código: Selecionar todos

#include "c:\clipper5\include\extend.api"
#include "c:\c700\include\stdlib.h"
#include "c:\c700\include\string.h"
#include "c:\c700\include\math.h"

#define SOMA          0
#define SUBTRACAO     1
#define MULTIPLICACAO 2
#define DIVISAO       3
#define PRECISAO     20

double par1, par2;
int decimal;
char result[21];

void do_oper(int oper)
  {double r1, err;
   int dec, sig, aux;
   char err_c[PRECISAO+1];
   strcpy(err_c, "0.");
   aux = decimal;
   while(aux != 0)
     {strcat(err_c, "0");
      aux--;
     }
   strcat(err_c, "1");
   err = atof(err_c);
   switch(oper)
     {case SOMA:
        r1 = par1 + par2;
        break;
      case SUBTRACAO:
        r1 = par1 - par2;
        break;
      case MULTIPLICACAO:
        r1 = (par1 * par2);
        break;
      case DIVISAO:
        r1 = (par1 / par2);
        break;
     }
   if(r1 > 0)
      r1 += err;
   else
      r1 -= err;
   strcpy(result, ecvt(r1, PRECISAO, &dec, &sig));
   if(dec<1)
     {char ret[PRECISAO+1];
      if( ((sig!=0)&&(dec<2-PRECISAO)) || ((sig==0)&&(dec<1-PRECISAO)) || (dec<=-(decimal)) )
        {strcpy(ret, "0.");
         if(decimal>0)
           {aux = decimal;
            while(aux>0)
              {strcat(ret, "0");
               aux--;}
           }
         strcpy(result, ret);
        }
      else
        {strcpy(ret, "0.");
         aux = dec;
         while(aux<0)
           {strcat(ret, "0");
            aux++;
           }
         strncat(ret, result, decimal+dec);
         strcpy(result, ret);
         if(sig!=0)
           {strcpy(ret, "-");
            strncat(ret, result, PRECISAO-1);
            strcpy(result, ret);
           }
        }
     }
   else
     {if( ((sig==0)&&(dec>PRECISAO)) || ((sig!=0)&&(dec>PRECISAO-1)) )
        {strcpy(result, "*");
         aux = PRECISAO-1;
         while(aux>0)
           {strcat(result, "*");
            aux--;
           }
        }
      else
        {char ret1[PRECISAO+1], ret2[PRECISAO+1];
         strcpy(ret1, "");
         strncat(ret1, result, dec);
         if((sig==0)&&(dec>(PRECISAO-2)) || ((sig!=0)&&(dec>(PRECISAO-3))))
            strcpy(result, ret1);
         else
           {strcat(ret1, ".");
            strcpy(ret2, " ");
            strncat(ret2, result, PRECISAO-1);
            memmove(ret2, ret1, dec+1);
            strcpy(result, "");
            strncat(result, ret2, dec+1+decimal);
           }
         if(sig!=0)
           {strcpy(ret1, "-");
            strncat(ret1, result, PRECISAO-1);
            strcpy(result, ret1);
           }
        }
     }
   return;
  }

CLIPPER c_sum()
  {if(ISCHAR(1))
      par1 = atof(_parc(1));
   else
      par1 = _parnd(1);

   if(ISCHAR(2))
      par2 = atof(_parc(2));
   else
      par2 = _parnd(2);

   if(PCOUNT == 3)
     {decimal = _parni(3);
      if(decimal > 10)
         decimal = 10;
      else if(decimal < 0)
         decimal = 0;
     }
   else
      decimal = 2;

   do_oper(SOMA);

   _retc(result);}

CLIPPER c_sub()
  {if(ISCHAR(1))
      par1 = atof(_parc(1));
   else
      par1 = _parnd(1);

   if(ISCHAR(2))
      par2 = atof(_parc(2));
   else
      par2 = _parnd(2);

   if(PCOUNT == 3)
     {decimal = _parni(3);
      if(decimal > 10)
         decimal = 10;
      else if(decimal < 0)
         decimal = 0;
     }
   else
      decimal = 2;

   do_oper(SUBTRACAO);

   _retc(result);}

CLIPPER c_mult()
  {if(ISCHAR(1))
      par1 = atof(_parc(1));
   else
      par1 = _parnd(1);

   if(ISCHAR(2))
      par2 = atof(_parc(2));
   else
      par2 = _parnd(2);

   if(PCOUNT == 3)
     {decimal = _parni(3);
      if(decimal > 10)
         decimal = 10;
      else if(decimal < 0)
         decimal = 0;
     }
   else
      decimal = 2;

   do_oper(MULTIPLICACAO);

   _retc(result);}

CLIPPER c_div()
  {if(ISCHAR(1))
      par1 = atof(_parc(1));
   else
      par1 = _parnd(1);

   if(ISCHAR(2))
      par2 = atof(_parc(2));
   else
      par2 = _parnd(2);

   if(par2==0)
     {printf("Erro de divisao por zero!");
      exit(0);
     }
   else
     {if(PCOUNT == 3)
        {decimal = _parni(3);
         if(decimal > 10)
            decimal = 10;
         else if(decimal < 0)
            decimal = 0;
        }
      else
         decimal = 2;

      do_oper(DIVISAO);

      _retc(result);
     }
  }

►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
rmg
Usuário Nível 1
Usuário Nível 1
Mensagens: 27
Registrado em: 02 Mar 2006 11:54
Localização: Ipanema/MG

Ajuda com código em C - Arredondamento de valores

Mensagem por rmg »

Amigo,

As diferenças são mínimas na conversão do C para Harbour em comparação com o Clipper. Segue o código convertido abaixo:

Código: Selecionar todos

FUNCTION MAIN
	aa := 0.00
	bb := 0.00
	continua = .T.
	while continua
	   cls
	   @ 0,0 say "a" get aa picture "9999999999999999.99"
	   @ 1,0 say "b" get bb picture "9999999999999999.99"
	   read
	   if lastkey()<>27
	      cls
	      ? "valores:"
	      ? aa, bb
	      ?
	      ? "opera‡oes em clipper:"
	      ? aa+bb
	      ? aa-bb
	      ? aa*bb
	      ? aa/bb
	      ? round(aa/bb,4)
	      ?
	      ? "opera‡oes em c:"
	      ? c_sum(aa, bb)
	      ? c_sub(aa, bb)
	      ? c_mult(aa, bb)
	      ? c_div(aa, bb)
	      ?
	      ? "tecle qualquer tecla para continuar..."
	      inkey(0)
	   else
	      continua = .F.
	   endif
	end
	return



#pragma BEGINDUMP

#include "hbapi.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
 
#define SOMA          0
#define SUBTRACAO     1
#define MULTIPLICACAO 2
#define DIVISAO       3
#define PRECISAO     20
 
double par1, par2;
int decimal;
char result[21];
 
void do_oper(int oper)
  {double r1, err;
   int dec, sig, aux;
   char err_c[PRECISAO+1];
   strcpy(err_c, "0.");
   aux = decimal;
   while(aux != 0)
     {strcat(err_c, "0");
      aux--;
     }
   strcat(err_c, "1");
   err = atof(err_c);
   switch(oper)
     {case SOMA:
        r1 = par1 + par2;
        break;
      case SUBTRACAO:
        r1 = par1 - par2;
        break;
      case MULTIPLICACAO:
        r1 = (par1 * par2);
        break;
      case DIVISAO:
        r1 = (par1 / par2);
        break;
     }
   if(r1 > 0)
      r1 += err;
   else
      r1 -= err;
   strcpy(result, ecvt(r1, PRECISAO, &dec, &sig));
   if(dec<1)
     {char ret[PRECISAO+1];
      if( ((sig!=0)&&(dec<2-PRECISAO)) || ((sig==0)&&(dec<1-PRECISAO)) || (dec<=-(decimal)) )
        {strcpy(ret, "0.");
         if(decimal>0)
           {aux = decimal;
            while(aux>0)
              {strcat(ret, "0");
               aux--;}
           }
         strcpy(result, ret);
        }
      else
        {strcpy(ret, "0.");
         aux = dec;
         while(aux<0)
           {strcat(ret, "0");
            aux++;
           }
         strncat(ret, result, decimal+dec);
         strcpy(result, ret);
         if(sig!=0)
           {strcpy(ret, "-");
            strncat(ret, result, PRECISAO-1);
            strcpy(result, ret);
           }
        }
     }
   else
     {if( ((sig==0)&&(dec>PRECISAO)) || ((sig!=0)&&(dec>PRECISAO-1)) )
        {strcpy(result, "*");
         aux = PRECISAO-1;
         while(aux>0)
           {strcat(result, "*");
            aux--;
           }
        }
      else
        {char ret1[PRECISAO+1], ret2[PRECISAO+1];
         strcpy(ret1, "");
         strncat(ret1, result, dec);
         if((sig==0)&&(dec>(PRECISAO-2)) || ((sig!=0)&&(dec>(PRECISAO-3))))
            strcpy(result, ret1);
         else
           {strcat(ret1, ".");
            strcpy(ret2, " ");
            strncat(ret2, result, PRECISAO-1);
            memmove(ret2, ret1, dec+1);
            strcpy(result, "");
            strncat(result, ret2, dec+1+decimal);
           }
         if(sig!=0)
           {strcpy(ret1, "-");
            strncat(ret1, result, PRECISAO-1);
            strcpy(result, ret1);
           }
        }
     }
   return;
  }
 
HB_FUNC(C_SUM)
  {if(ISCHAR(1))
      par1 = atof(hb_parc(1));
   else
      par1 = hb_parnd(1);
 
   if(ISCHAR(2))
      par2 = atof(hb_parc(2));
   else
      par2 = hb_parnd(2);
 
   if(hb_pcount() == 3)
     {decimal = hb_parni(3);
      if(decimal > 10)
         decimal = 10;
      else if(decimal < 0)
         decimal = 0;
     }
   else
      decimal = 2;
 
   do_oper(SOMA);
 
   hb_retc(result);}
 
HB_FUNC(C_SUB)
  {if(ISCHAR(1))
      par1 = atof(hb_parc(1));
   else
      par1 = hb_parnd(1);
 
   if(ISCHAR(2))
      par2 = atof(hb_parc(2));
   else
      par2 = hb_parnd(2);
 
   if(hb_pcount() == 3)
     {decimal = hb_parni(3);
      if(decimal > 10)
         decimal = 10;
      else if(decimal < 0)
         decimal = 0;
     }
   else
      decimal = 2;
 
   do_oper(SUBTRACAO);
 
   hb_retc(result);}
 
HB_FUNC(C_MULT)
  {if(ISCHAR(1))
      par1 = atof(hb_parc(1));
   else
      par1 = hb_parnd(1);
 
   if(ISCHAR(2))
      par2 = atof(hb_parc(2));
   else
      par2 = hb_parnd(2);
 
   if(hb_pcount() == 3)
     {decimal = hb_parni(3);
      if(decimal > 10)
         decimal = 10;
      else if(decimal < 0)
         decimal = 0;
     }
   else
      decimal = 2;
 
   do_oper(MULTIPLICACAO);
 
   hb_retc(result);}
 
HB_FUNC(C_DIV)
  {if(ISCHAR(1))
      par1 = atof(hb_parc(1));
   else
      par1 = hb_parnd(1);
 
   if(ISCHAR(2))
      par2 = atof(hb_parc(2));
   else
      par2 = hb_parnd(2);
 
   if(par2==0)
     {printf("Erro de divisao por zero!");
      exit(0);
     }
   else
     {if(hb_pcount() == 3)
        {decimal = hb_parni(3);
         if(decimal > 10)
            decimal = 10;
         else if(decimal < 0)
            decimal = 0;
        }
      else
         decimal = 2;
 
      do_oper(DIVISAO);
 
      hb_retc(result);
     }
  }
  
#pragma ENDDUMP
Abraços,
Renato Martins
Analista de TI - Grupo Colombo<br>
Harbour, xHarbour, C, C++
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Ajuda com código em C - Arredondamento de valores

Mensagem por asimoes »

Renato,

Obrigado pela conversão, temos um sistema que em clipper usava as funções em C e na conversão para harbour tem que resultar os mesmos valores.

[]´s
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Responder