Comparação de Doubles
Olá pessoal, tenho 2 cpos Doubles: D1,D2.
D1 provém da soma de um grupo de Doubles c/ 1 decimal.
D2 provém da soma de outro grupo de Doubles c/ 1 decimal.
Pelo Debug do Delphi, quando clico Ctrl+F7 em D1, ele me mostra:307.3
quando clico Ctrl+F7 em D2, ele me mostra:307.3
Quando faço: if D1 = D2; ele me retorna false.
Quando faço: if Trunc(D1*10) = Trunc(D2*10); ele me retorna false.
Quando faço: if Round(D1*10) = Round(D2*10); ele me retorna true.
Alguém por acaso saberia um jeito de comparar 2 Doubles ?
Antecipados agradecimentos . . .
D1 provém da soma de um grupo de Doubles c/ 1 decimal.
D2 provém da soma de outro grupo de Doubles c/ 1 decimal.
Pelo Debug do Delphi, quando clico Ctrl+F7 em D1, ele me mostra:307.3
quando clico Ctrl+F7 em D2, ele me mostra:307.3
Quando faço: if D1 = D2; ele me retorna false.
Quando faço: if Trunc(D1*10) = Trunc(D2*10); ele me retorna false.
Quando faço: if Round(D1*10) = Round(D2*10); ele me retorna true.
Alguém por acaso saberia um jeito de comparar 2 Doubles ?
Antecipados agradecimentos . . .
Ipc$
Curtidas 0
Respostas
Ipc$
16/06/2005
Esquecí de mencionar que os grupos originais p/ a soma estão c/ 1 decimal pq sua resultante final é:
Trunc(Valor) / 10;
GOSTEI 0
Ipc$
16/06/2005
Ninguém ?
GOSTEI 0
Bruno Belchior
16/06/2005
declare a unit [b:194441fa78]Math[/b:194441fa78] e use comparando a função [b:194441fa78]RoundTo[/b:194441fa78]...Onde o segundo parâmetro é a quantidade de casas a ser arredondada...
if RoundTo(10.5555555,2) = RoundTo(10.555555556,2) then
GOSTEI 0
Beppe
16/06/2005
Existe a rotina SameValue, tbm em Math que permite verificar se dois números são próximos dado um Delta.
SameValue(A, B) usa o erro padrão, mas pode usar outro(SameValue(A, B, MaxDiff)).
SameValue(A, B) usa o erro padrão, mas pode usar outro(SameValue(A, B, MaxDiff)).
GOSTEI 0
Ipc$
16/06/2005
Mas o que eu não entendo é que todos os Doubles são a resultante de:
Trunc(Valor) / 10.
Para mim isso significa que todos estão com 1 decimal, portanto seu somatório resultará sempre em 1 decimal.
Pq então é gerado um flutuante com mais decimais ?
Trunc(Valor) / 10.
Para mim isso significa que todos estão com 1 decimal, portanto seu somatório resultará sempre em 1 decimal.
Pq então é gerado um flutuante com mais decimais ?
GOSTEI 0
Beppe
16/06/2005
Realmente é um troço complicado de entender, tem a ver com a maneira com que FP´s são armazenados(mantissa, expoente e sinal), eles sofrem por normalização e bias, e sempre há erros de arredondamento com eles. A solução seria usar ponto fixo, como o Currency.
Se te interessar mais sobre FP´s e souber inglês, google-it: ´What every computer scientist should know about floating point arithmetic´...o título é algo assim.
Se te interessar mais sobre FP´s e souber inglês, google-it: ´What every computer scientist should know about floating point arithmetic´...o título é algo assim.
GOSTEI 0
Ipc$
16/06/2005
Tentei com Currency e o comportamento foi idêntico.
Bom, não vou mais me aprofundar nisso e a solução satisfatória que encontrei p/ esse tipo de comparação foi:Acredito que não seja a forma ideal, mas funciona.
Bom, não vou mais me aprofundar nisso e a solução satisfatória que encontrei p/ esse tipo de comparação foi:
if (D1 = D2) or (Trunc(D1*10) = Trunc(D2*10)) or (Round(D1*10) = Round(D2*10)) then Result := true else Result := false;
GOSTEI 0