Ir para conteúdo
  • Cadastre-se

dev botao

Problemas Na Funcao Lfill


  • Este tópico foi criado há 3567 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

boa tarde,

 

estou com prob na funcao  LFill para formatar valor e por texto com 3 casas decimais

 

 

o problema pelo q vi eh no tipo da variavel   Extended passado no parametro da funcao ...

 

ACBrTXTClass 

 

   function TACBrTXTClass.LFill(Value: Extended;
                        Size: Integer;
                        Decimal: Integer = 2;
                        Nulo: Boolean = false;
                        Caracter: Char = '0';
                        Mascara: String = ''): String;

 

Result := LFill(Trunc(Value * intP), Size, Nulo, Caracter);

 

 

ela nao guarda o valor 1 em (0,001 * 1000)  deve guardar tipo ...  0,999999999999999..... entao no trunc zera....

 

se alterar o tipo para currency ou double funciona....

 

para ver esta dif pode ser feito  

var1 : extended

var2 : currency

 

e um showmessage   var1 - var2   ..

 

pra mim deu   

---------------------------
Project3
---------------------------
-2,08581863261371E-20
---------------------------
OK  
---------------------------

 

 

 

provavelmmt teria q trocar os fontes de Extended para double

 

 

 

Link para o comentário
Compartilhar em outros sites

a chamada da funcao

   function TACBrTXTClass.LFill(Value: Extended;
                        Size: Integer;
                        Decimal: Integer = 2;
                        Nulo: Boolean = false;
                        Caracter: Char = '0';
                        Mascara: String = ''): String;

 

via  a classe ACBrPAF_R_Class    no ponto LFill(QTDE_ITEM, 7, QTDE_DECIMAL)   linha 523   qtde_item = 0,001 e qtd decimal = 3

 

 

dentro dela chama novamente

   Result := LFill(Trunc(Value * intP), Size, Nulo, Caracter);   linha 283  classe ACBrTXTClass

 

passando Result := LFill(Trunc(0,001 * 1000), Size, Nulo, Caracter);  

 

 

o retorno eh de 0000000  em vez de 0000001

Link para o comentário
Compartilhar em outros sites

Bom dia, esse tipo foi mudado, antes se me lembro bem quando criei o componente tudo era currency, mas por algum motivo do qual não me lembro alguém mudou para Extended (acredito que tenha sido por motivo de muitas casas decimais, que o tipo currency não atende), tente fazer uma pesquisa no fórum e encontre o motivo dessa mudança para analisarmos como podemos solucionar o problema.

--
Isaque Pinheiro
Aracruz/ES - Brasil
___________________________________________________________________________
Site Oficial: www.isaquepinheiro.com.br 
Youtube: youtube.com/isaquepinheirooficialbr
Facebook: facebook.com.br/isaquepinheirooficialbr
Instagram: instagram.com/isaquepinheirooficialbr
Linkdin: https://www.linkedin.com/in/isaquepinheirooficialbr

Conheça o Projeto ORMBr Framework for Delphi - https://www.ormbr.com.br

 

Link para o comentário
Compartilhar em outros sites

  • Consultores

   Estou achando muito estranho o tipo Extended não conseguir comportar uma precisão tão pequena nos cálculos.

   A princípio ele deveria ter um suporte maior a números significativos que o tipo Double.

 

   Buffon, a mudança para o tipo Extended foi para que pudesse ser permitido alguns casos onde havia necessidade de até 6 casas decimais. Como sugerido, você pesquisou aqui no fórum para encontrar o tópico sobre a mudança?

   Se a mudança para Double não afetar o problema das 6 casas decimais, acho que não haverá algum problema. Estou começando a achar que deveríamos adicionar alguns testes unitários nessas funções do SPED. o.o''

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

acho q o extended suporte muita precisao que o calculo 0,001 * 1000 em vez de ficar 1 fica 0,99999999 etc ...

 

faca um teste simples no delphi  segue codigo...

 

 

 

procedure TForm6.Button1Click(Sender: TObject);
var
   a : double;
   b : extended;
begin

  a := 0.001 * 1000;
  b := 0.001 * 1000;

  showmessage(floattostr(a-B));

end;

 

teoricamente deveria de dar zero ..certo ?

 

 

 

procurei hoje  d manha mas nao achei no forum..vou dar mais uma olahda na tarde...

Link para o comentário
Compartilhar em outros sites

  • Consultores

Acho que entendi o problema. Tente o seguinte código:

procedure TForm6.Button1Click(Sender: TObject);
var
  a : double;
  b : extended;
begin
  a := 0.001 * 1000.0;
  b := 0.001 * 1000.0;
  showmessage(floattostr(a-B));
end;

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

boa tarde...

 

funciona...mas acho q nao seria a melhor forma para correcao...

 

e..ate eh no proprio cod da acbr que faz o   * 1000  ..onde 1000 eh o parametro das casas decimais

 

segue o cod  linha 275

 

  for intFor := 1 to Decimal do
  begin
     intP := intP * 10;
  end;

 

a alteracao foi feita devido

 

mas currency..tudo bem...4 casas pouco... mas o double se nao me engano eh 16 casas

 

seria possivel alterar o codigo para double ?

Link para o comentário
Compartilhar em outros sites

  • Consultores

Vai ser preciso testar se não vai acontecer nenhum problema. Se não der nenhum problema, então tudo bem.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • Consultores

Devo verificar isso amanhã pela manhã. No máximo até sexta eu tenho um parecer.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

eu alterei para double nos meus fontes... porem hoje testando novamnte

 

passando um valor 0,48 .. no arquov esta gerando 00047 ...

 

teste  ... nao retorna zero...

 

var
  a : currency;
  b : double;
begin
  a := 0.48;
  b:= 0.48;

  showmessage(floattostr(a-B))

 

 

 

e a funcao dentro do lfill qdo dah um trunc passando como parametro trunc(0,48 *100)   o 100 eh o calculo do acbr

  for intFor := 1 to Decimal do
  begin
     intP := intP * 10;
  end;

 

 

esta passando ,47 no trunc...

 

acho q teria q rever esta forma de conversao ... jah que alguns depende de mais casas decimais na funcao

Link para o comentário
Compartilhar em outros sites

  • Consultores

  Essas diferenças sempre vão ocorrer com os tipos de ponto flutuante. Eu sempre tenho muito problemas com o tipo Double e foi exatamente por isso que mudei pra Extended.

  Veja alguns exemplos de perguntas motivadas por essa diferença:

https://stackoverflow.com/questions/5191235/why-is-the-result-of-roundto87-285-2-87-28

https://stackoverflow.com/questions/6106119/how-to-compare-double-in-delphi

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois ...
  • Consultores

Bom para reproduzir o problema e verificar, veja essa aplicação console. Ela reproduz o problema de forma resumida. Não adicionei outros exemplos de problemas que ocorrem com Double mas não acontecem com Extended ainda devido ao tempo.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Math;


var
  valorDouble: Double;
  valorExtended: Extended;
  valorCurrency, aa: Currency;

begin
  try
    valorDouble   := 0.001;
    valorExtended := 0.001;
    valorCurrency := 0.001;
    Writeln('--- Codigo atual --');
    //////Atual
    Writeln('Double   -> ', Trunc(valorDouble   * 1000));
    Writeln('Currency -> ', Trunc(valorCurrency * 1000));
    Writeln('Extended -> ', Trunc(valorExtended * 1000));
    Writeln('');
    Writeln('--- Correcao?? --');
    ///Testes
    Writeln('Trunc(1.0000001) -> ', Trunc(1.0000001));
    Writeln('Trunc(0.001 * 1000.0)   -> ', Trunc(0.001 * 1000.0));
    Writeln('Trunc(0.0010 * 1000.0)  -> ', Trunc(0.0010 * 1000.0));
    Writeln('Trunc(0.00100 * 1000.0) -> ', Trunc(0.00100 * 1000.0));

    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

neste seu teste ...se deixar extended  fica Zero (errado)

 

double e currency fica = 1 (certo)

 

ok?

 

 

agora teste add

 

    valorDouble   := 0.48;
    writeln(trunc(valorDouble * 100));
    writeln(valorDouble * 100);

 

o trunc deveria ficar com 48...mas fica 47

 

 

com o currency fica certo (48)

Link para o comentário
Compartilhar em outros sites

  • Consultores

E o valor com Extended fica certo também.

    Writeln('---');
    valorDouble   := 0.48;
    valorCurrency   := 0.48;
    valorExtended   := 0.48;
    writeln(trunc(valorDouble * 100));
    writeln(trunc(valorCurrency * 100));
    writeln(trunc(valorExtended * 100));

E aí?

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • 1 mês depois ...

Ola Amigos Brasileiro e criativo então vamos as duas Gambiarras que testei e funciona legal aqui.
 

function TACBrTXTClass.LFill(Value: Extended;
                        Size: Integer;
                        Decimal: Integer = 2;
                        Nulo: Boolean = false;
                        Caracter: Char = '0';
                        Mascara: String = ''): String;
var
intFor, intP, intValor: Integer;
strCurMascara, strValor: string;
begin
  strCurMascara := FCurMascara;
  // Se recebeu uma mascara como parametro substitue a principal
  if Mascara <> '' then
     strCurMascara := Mascara;
 
  /// Se o parametro Nulo = true e Value = 0, será retornado '|'
  if (Nulo) and (Value = 0) then
  begin
     Result := FDelimitador;
     Exit;
  end;
  intP := 1;
  for intFor := 1 to Decimal do
  begin
     intP := intP * 10;
  end;
 
  if (strCurMascara <> '#') and (strCurMascara <> '') then
     Result := FDelimitador + FormatCurr(strCurMascara, Value)
  else
  begin
    (* Este método também funciona - GAMBIARRA NUMERO 1
    // Recebe o valor truncado.
    intValor := Integer(Trunc(Value * intP));
 
    // devido ao bug do método Trunc, alguns valores retornam abaixo do esperado.
    f := Frac(Value * intP);
 
    // Outro bug de comparação do delphi, "1" não é igual a "1" usando o operador "="
    if SameValue(f, 1) then
      Inc(intValor);
    //
    *)
 
 
    //ou GAMBIARRA NUMERO 2
    strValor := FloatToStr(Value * intP);
 
    intValor := Pos(',', strValor);
 
    if intValor > 0 then
      intValor := StrToInt( Copy(strValor, 1, intValor -1) )
    else
      intValor := StrToInt(strValor);
 
    Result := LFill(intValor, Size, Nulo, Caracter);
  end;
end;

 

ACBrTXTClass.pas

Link para o comentário
Compartilhar em outros sites

  • Consultores

Olá asterix,

 

  O seu código parece estar correto. Estou adicionando uma aplicação para testes aqui. Qualquer um pode adicionar outros exemplos de erro ou testes necessários ou mesmo sugerir uma correção utilizando o exemplo que estou anexando aqui.

 

  Não havendo nenhuma objeção, vamos integrar o código ao SVN.

 

 

Project1.zip

  • Curtir 1

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • 6 meses depois ...
  • Consultores

Esse assunto foi resolvido e enviado ao SVN hoje utilizando outro método.

Mais informações sobre a correção desse problema no seguinte tópico:

 

Estou fechando esse tópico para não haver duplicação de informações.

Por favor, continuem no tópico acima.

  • Curtir 1

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 3567 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.