Recent

Author Topic: Firebird 3 + Laz64 + TSQLQuery currency error  (Read 7811 times)

ttomas

  • Full Member
  • ***
  • Posts: 245
Re: Firebird 3 + Laz64 + TSQLQuery currency error
« Reply #15 on: October 21, 2021, 12:11:41 am »
Reading about currency Issue on x64 function IntPower10  line 1057 in IBConnection.pp should be checked
Code: [Select]
function IntPower10(e: integer): double;
const PreComputedPower10: array[0..9] of integer = (1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000);
var n: integer;
begin
  n := abs(e); //exponent can't be greater than 18
  if n <= 9 then
    Result := PreComputedPower10[n]
  else
    Result := PreComputedPower10[9] * PreComputedPower10[n-9];
  if e < 0 then
    Result := 1 / Result;
end;


LacaK

  • Hero Member
  • *****
  • Posts: 691
Re: Firebird 3 + Laz64 + TSQLQuery currency error
« Reply #16 on: October 22, 2021, 08:41:51 am »
On Win64 you can reproduce problem by simple test (not related to IBConnection):
Code: Pascal  [Select][+][-]
  1. var
  2.   c: currency;
  3.   d: double;
  4.   i1: int64;
  5. begin
  6.   c:=1115;
  7.   d:=100000000;
  8.   i1:=Round(c*d);
  9.   writeln(i1);
  10. end;
  11.  
Compare result for Win32 and Win64 ...

LacaK

  • Hero Member
  • *****
  • Posts: 691
Re: Firebird 3 + Laz64 + TSQLQuery currency error
« Reply #17 on: October 25, 2021, 08:52:24 am »
Something like this may help:

Code: Pascal  [Select][+][-]
  1.       SQL_INT64:
  2.           begin
  3.             if VSQLVar^.sqlscale = 0 then
  4.               li := AParam.AsLargeInt
  5.             else if AParam.DataType = ftFMTBcd then
  6.               li := AParam.AsFMTBCD * IntPower10(-VSQLVar^.sqlscale)
  7.             else if AParam.DataType = ftCurrency then
  8.               if -VSQLVar^.sqlscale >= 4 then
  9.                 li := Round(AParam.AsCurrency * 10000) * Trunc(IntPower10(-VSQLVar^.sqlscale-4))
  10.               else
  11.                 li := Round(AParam.AsCurrency * IntPower10(-VSQLVar^.sqlscale-4))
  12.             else
  13.               li := Round(AParam.AsFloat * IntPower10(-VSQLVar^.sqlscale));
  14.             Move(li, VSQLVar^.SQLData^, VSQLVar^.SQLLen);
  15.           end;
« Last Edit: October 25, 2021, 08:55:38 am by LacaK »

lmdamiano

  • New member
  • *
  • Posts: 9
Re: Firebird 3 + Laz64 + TSQLQuery currency error
« Reply #18 on: November 04, 2021, 11:35:46 am »
The problem can be temporarily solved through a class helper for TParam

Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   { TParamHelper }
  4.  
  5.   TParamHelper = class helper for TParam
  6.      protected
  7.        procedure setAsCurrencyBCD(pValore : Currency);
  8.        function getAsCurrencyBCD() : Currency;
  9.      published
  10.        property AsCurrency : Currency read GetAsCurrencyBCD write SetAsCurrencyBCD;
  11.   end;  
  12.  

Code: Pascal  [Select][+][-]
  1. { TParamHelper }
  2. procedure TParamHelper.setAsCurrencyBCD(pValore: Currency);
  3. begin
  4.   Self.AsFMTBCD := CurrToBCD(pValore);
  5. end;
  6.  
  7. function TParamHelper.getAsCurrencyBCD(): Currency;
  8. begin
  9.   BCDToCurr(GetAsFMTBCD, Result);
  10. end;  
  11.  

with this little class helper TParam .asCurrency will work without rewriting all the references. You could put this class helper behind a conditional formatting like {$IF FPC_FULLVERSION > 30000}.
I like those new tricks.

 

TinyPortal © 2005-2018