### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

#### ttomas

• Full Member
• Posts: 233
##### 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: 651
##### 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: 651
##### 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.