Porque o delphi inciste q os valores sao diferentes?

Delphi

10/08/2006

Olá amigos, estou tentando solucionar um problemão... tenho um conta a pagar no valor de R$ 102,45, dividido em 3 parcelas com Entrada de R$ 10,00... sem problemas... fiz os calculos e tals.. aí eu verifico se as parcelas tem alguma diferencao com o valor final, com o seguinte codigo:

  ValorReal := 0;
  TbParcelas.First;
  while not TbParcelas.EOF do
  begin
    if (not Empty(TbParcelasCOD_BOLETA.AsString)) and (Trim(TbParcelasTIPO_DOC.AsString) <> ´4´) then
    begin
      TbParcelas.Edit;
      TbParcelasCOD_BOLETA.Clear;
      TbParcelas.Post;
    end;
    ValorReal := ValorReal + ExatoCurrency(TbParcelasVALOR.AsCurrency, 2);
    TbParcelas.Next;
  end;

  ValorReal := ExatoCurrency(ValorReal, 2);
  if ValorReal <> ExatoCurrency(TbPrincipalVALOR_VENDA.AsCurrency, 2) then
  begin
    Application.MessageBox(PChar(´Existe uma diferença de R$ ´ + FormatFloat(´#0.00´, ValorReal) + ´ no somatório das parcelas´), ´Atenção´, MB_OK + MB_ICONEXCLAMATION + MB_DEFBUTTON1 + MB_APPLMODAL);
    Exit;
  end;


O conteúdo da minha variavel [b:b2b26be19a]ValorReal[/b:b2b26be19a] é de 102,45 e o conteúdo do meu [b:b2b26be19a]TbPrincipalVALOR_VENDA.AsCurrency[/b:b2b26be19a] também é de 102,45

Mas no if embaixo, ele fala que é diferente.. como pode ser? Já debuguei já fiz de tudo, as duas são iguais... o que pode ser?


Desde já agradeço...

[]s


Titanius

Titanius

Curtidas 0

Respostas

Paullsoftware

Paullsoftware

10/08/2006

só pra teste tente jogar os dois valores para ums string e veja se os valores continuam os mesmos...

uma vez aconteceu um caso semelhante com migo, mais foi problemas de arredondamento dos valores mesmo, ele mostrava +/- assim: 1,61 mais o real era 1,60,9 joguei numa string e ví onde tava o problema, não quero dizer que pode ser a mesma coisa mais, vai lá saber né :lol:


GOSTEI 0
Marco Salles

Marco Salles

10/08/2006

Acho que é por ai tb....

só pra teste tente jogar os dois valores para ums string e veja se os valores continuam os mesmos...


represntação interna do currency...

Porque disso ???

Lembra do tópico

http://forum.clubedelphi.net/viewtopic.php?t=78527&highlight=currency

Uma saida talvez e na comparação truncar em uma quantidade de casas decimais

So não entendi no seu codigo quem é ExatoCuurency

 ValorReal := ValorReal + ExatoCurrency
.......
.......
 ValorReal := ExatoCurrency(ValorReal, 2); 



GOSTEI 0
Titanius

Titanius

10/08/2006

Olá amigos, o ExatoCurrency, e uma função que peguei aqui mesmo no forum, que me retorna um numero com as ]quantidades de casas decimais que eu quero..

Acho que meu problema era por ValorREal ser decladora como Real...

só troquei isso no codigo:

if [b:0369777367]ExatoCurrency([/b:0369777367]ValorReal[b:0369777367], 2)[/b:0369777367] <> ExatoCurrency(TbPrincipalVALOR_VENDA.AsCurrency, 2) then


que funcionou.. estranho, nunca vou entender esse sistema de numeração do Delphi...

[b:0369777367]Marco Salles[/b:0369777367]:

Agora que percebi meu, você é da minha cidade.... trabalha onde?


[]s


GOSTEI 0
Marco Salles

Marco Salles

10/08/2006

só troquei isso no codigo: if ExatoCurrency(ValorReal, 2) <> ExatoCurrency(TbPrincipalVALOR_VENDA.AsCurrency, 2) then


Claro , pois como foi sugerido:

Uma saida talvez e na [b:83f4efaa24]comparação[/b:83f4efaa24] truncar em uma quantidade de casas decimais


Marco Salles: Agora que percebi meu, você é da minha cidade.... trabalha onde?


Voce ja percebeu isto outras vezes... é pq vc esquece
Ja ate fez esta pergunta:D :D :D :D


GOSTEI 0
Titanius

Titanius

10/08/2006

hehe.. verdade?! vixi, to ruim de cabeça mesmo... talvez nos encontramos e nem faço idéia.. :roll:

[]s


GOSTEI 0
Dmalta

Dmalta

10/08/2006

O problema de arredondamento não é do Delphi, mas uma limitação dos processadores, que usam representação numérica de ponto flutuante. Deixando a teoria de lado, eu costumo usar duas técnicas pra lidar com esses problemas.

Uma é forçar o arredondamento em código do número de casas decimais usando RoundTo.
uses Math;
{...}
X := RoundTo(X, -2);

Quando não é interessante arredondar os fatores da expressão e só queremos comparar dois valores de ponto flutuante em determinada precisão, comparo limitando um coeficiente de precisão (´[i:d8dc8e2d49]epsilon[/i:d8dc8e2d49]´).

A unit [i:d8dc8e2d49]Math[/i:d8dc8e2d49] já tem uma função prontinha pra isso (com overload para vários tipos de dados de ponto flutuante):
var
  Parcela, Total, A, B: Double;
begin
  Total := 102.45;
  Parcela := RoundTo((Total - 10) / 3, -3);
  A := Total;
  B := 3 * Parcela + 10;
  if SameValue(A, B, 3) then
    ShowMessage(´A e B são iguais´)
  else
    ShowMessage(Format(´A e B são DIFERENTES: A = ¬g e B = ¬g´, [A, B]))
end;

Trocando SameValue pela expressão ´(A = B)´ dá False, ao invés de True.

Just my 2 cents.

Um abraço,


GOSTEI 0
Marco Salles

Marco Salles

10/08/2006

interresante samueValue .. Eu não conhecia

Mas não sei se entendio direito fiz ums teste , trocando o valor 10 por StrtoFloat . Ficando assim :

var
  Parcela, Total, A, B: Double;
begin
  Total := 102.45;
  Parcela := RoundTo((Total - 10) / 3, -3);
  A := Total;
  B := 3 * Parcela +strtofloat(edit1.text);
  if SameValue(A, B, 3) then
    ShowMessage(Format(´A e B são iguais: A = ¬g e B = ¬g´, [A, B]))
  else
    ShowMessage(Format(´A e B são DIFERENTES: A = ¬g e B = ¬g´, [A, B]))


[b:7edb6704f2]
o engraçado é que com edit1.text = 6,99 diz que A e B são diferentes ... O que é verdade .. Porem para Edit1.text = 6,999 Diz que A e B são Iguais e mostar para A = 102,45 e B = 99,45
[/b:7edb6704f2]

Essa eu não entendi... :cry: :cry: :cry:


GOSTEI 0
POSTAR