[firebase-br] [meio OT] Campo decimal + delphi

Eduardo Jedliczka (TeamFB) jedyfb em gmail.com
Ter Jun 13 13:33:04 -03 2006


Entendo bem o seu problema...

Já precisei trabalhar com valores ínfimos que perdiam totalmente o sentido 
quando arredondados.

Mas saiba que a grande verdade é que pouquíssimos hardwares são preparados 
para trabalhar com mais de 15 casas decimais. Isto é uma limitação do 
co-processador matemático da família X86 de 32Bits. Quem sabe quando os 
processadores de 64bits forem a "plataforma mímina" para utilização, este 
limite suba para 127 ou 255 casas decimais.

Mas quanto à sua pergunta, é possível driblar este problema de várias 
formas, mas tenha consiência que isto não é uma coisa óbvia....

1º) Se eu sei que o PC não faz cálculos com mais de 15 casas decimais, por 
dedução, nem o windows, nem o Delphi e muito menos o FireBird o farão de 
forma "nativa".
2º) Você pode trabalhar com STRINGS para armazenar os valores, tanto no 
Delphi quanto no FireBird pois não há tipos de dados melhores.
3º) Crie funções e/ou UDFs para somar, subtrair, multiplicar ou dividir 
valores utilizando esta precisão. SEMPRE recebendo duas strings e retornando 
uma string.

Por exemplo:

Function SomaString( Vlr1, Vlr2: String):String;
var
  Vi1, Vf1: String;
  Vi2, Vf2 : String;
  Ri, Rf : String;
  p : Integer;
begin

  p := Pos('.', Vlr1); // procura o ponto do primeiro valor...
  if p <> 0 then
    begin
      Vi1 := Vlr1; // parte Inteira;
       Vf1 := '';  // parte Flutuante;
    end;
  else
    begin
       Vi1 := Copy(Vlr1,1,P-1);  // parte Inteira;
       Vf1 := Copy(Vlr1, P+1, 255); // parte Flutuante;
    end;

{
 faça isto com o segundo valor...

 faça um While para igualar o "tamanho" das casas decimais acrescentando 
"Zeros" à direita.

 Faça um While para igualar o "tamanho" dos números inteiros acrescentando 
"Zeros" à esquerda.

Faça um for, convertendo o "valor relativo" da posição da string em inteiro 
e realizando a operação matemática. Se exceder 10, acrescentar ao número do 
resultado da casa imediatamente anterior.

Exemplo:

números "1234567890.12345678901234567890" + "123.4567"

devem ficar

"1234567890" e "12345678901234567890"
"0000000123" e "45670000000000000000"

somando-se de trás para frente (caracter à caracter), enquanto não chegar ao 
"4567", teremos

"0000000000" e "00005678901234567890"

depois, ao convertermos os números 4 (do "1234...") e o 7 (do "4567"), e 
somarmos, teremos 11, que deverão formar o resultado:
"0000000000" e "00115678901234567890"

se repetirmos isto para a coluna anterior, teremos "3" e "6", com o resto 1 
que já está no "resultado".

só deve-se prestar atenção, que se a posição atual do ponto for na primeira 
casa, deve-se somar um no resultado da parte inteira...

No final, elimine os zeros à esquerda do Ponto e à direita do Ponto.
}

Result := Ri + '.' + Rf;
end;

Só para "terminarmos" o assunto... sim, isto é extremamente lento, e sim, dá 
muito trabalho...

======================
Eduardo Jedliczka
Membro do TeamFB - FireBase
Apucarana - PR
======================


----- Original Message ----- 
From: "Magnun Oliveira" <magnun_magnun em hotmail.com>
To: <lista em firebase.com.br>
Sent: Tuesday, June 13, 2006 10:28 AM
Subject: [firebase-br] [meio OT] Campo decimal + delphi


Tenho que fazer calculos com decimais de 18 casas. Declarei no fb
decimal(18,18 ) só que a parte inteira nunca vai ser maior que duas casas,
como devo declarar esse campo?

outra no delphi, um campo decimal(8,8) é do tipo TIBCDField e o 18,18 é
TFloatField. O decimal 8,8 tah normal, mas o 18,18 nao aceita o valo 10 por
ex...

alguma dica para isso?

_________________________________________________________________
MSN Busca: fácil, rápido, direto ao ponto.  http://search.msn.com.br


______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para editar sua configuração na lista, use o endereço 
http://mail.firebase.com.br/mailman/listinfo/lista_firebase.com.br
Para consultar mensagens antigas: http://firebase.com.br/pesquisa 





Mais detalhes sobre a lista de discussão lista