Lazarus

Free Pascal => General => Topic started by: Badger on June 27, 2020, 04:17:41 am

Title: Problem with Compare Value
Post by: Badger on June 27, 2020, 04:17:41 am
Moving all my programs to new computer and have a problem with one of my Lazarus projects.  The following code gives the error:"Can't determine which overload function to call" on the CompareValue line although it worked on myu old machine.

Code: Pascal  [Select][+][-]
  1. function CompareTextAsCurrency: Integer;                        // Float
  2.           var c1,c2:Currency;
  3.           begin
  4.             if TryStrToCurr(Table.Cells[ACol,ARow],c1) and
  5.                TryStrToCurr(Table.Cells[BCol,BRow],c2) then
  6.             Result := CompareValue((c1), c2)
  7.             else Exit(0);
  8.           end;
 

I have moved from Lazarus v1.8.4  to 2.0.8 with the latest version of FPC

I have done some looking but can't find info for this error relevant to this particular situation
Title: Re: Problem with Compare Value
Post by: Thaddy on June 27, 2020, 09:58:42 am
There is no overload for comparevalue(curr,curr) so the compiler can't decide.
It may be an idea to file a bug report and ask for a comparevalue for currency.
I have submitted a patch based on the code below...
See https://www.freepascal.org/docs-html/rtl/math/comparevalue.html
and https://bugs.freepascal.org/view.php?id=37275

E.g:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. uses math;
  3. // this could be added to math and satisfies the convention used for the others
  4. function CompareValue(const A, B  : Currency): TValueRelationship;
  5. begin
  6.   result:=GreaterThanValue;
  7.   if a=b then
  8.     result:=EqualsValue
  9.   else
  10.    if a<b then
  11.      result:=LessThanValue;
  12. end;
  13. //
  14. var
  15.   a,b: currency;
  16. begin
  17.   a:= 1.2345;
  18.   b:= 2.3456;
  19.   writeln(comparevalue(a,b));
  20. end.
I am surprised this worked previously... are you sure?
Anyway, with the above code it works and the patch also works on debian and windows.
Title: Re: Problem with Compare Value
Post by: Badger on June 27, 2020, 01:40:16 pm
Yes it worked before (and still works - compiles and runs) on my old puter.  As I say, on the new puter, I have used  updated Lazarus, FPC and the latest version of Windows 10 although Windows used to keep itself up to date.
Title: Re: Problem with Compare Value
Post by: PascalDragon on June 27, 2020, 03:32:36 pm
Can it be that you used 32-bit Lazarus on the old computer and 64-bit on the new one?
Title: Re: Problem with Compare Value
Post by: Thaddy on June 27, 2020, 07:05:37 pm
Before I provided the patch I tested multiple bitness and platforms. The error occurred on all. The provided patch (based on above code) solves it on all.
Since currency is technically not a float type it is also the correct way to solve it (imho)
Although I can not explain that the error did not show up on win32 as ASerge reported.
In my analyses this is simply by accident.
Title: Re: Problem with Compare Value
Post by: ASerge on June 28, 2020, 05:21:00 am
Although I can not explain that the error did not show up on win32 as ASerge reported.
Very simple. Project:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2.  
  3. uses Math;
  4.  
  5. var
  6.   C1: Currency = 0;
  7.   C2: Currency = 0;
  8.   B: TValueRelationship;
  9. begin
  10.   B := CompareValue(C1, C2);
  11. end.

Compile it:
Quote
...\fpc\3.0.4\bin\i386-win32\fpc.exe "...\project1.lpr"
Free Pascal Compiler version 3.0.4 [2020/04/11] for i386
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling ...\project1.lpr
project1.lpr(8,3) Note: Local variable "B" is assigned but never used
Linking ...\project1.exe
12 lines compiled, 0.2 sec, 64256 bytes code, 4164 bytes data
1 note(s) issued
Win32 - OK

Quote
...\fpc\3.0.4\bin\x86_64-win64\fpc.exe "...\project1.lpr"
Free Pascal Compiler version 3.0.4 [2020/04/11] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling ...\project1.lpr
project1.lpr(10,8) Error: Can't determine which overloaded function to call
project1.lpr(13) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: ...\fpc\3.0.4\bin\x86_64-win64\ppcx64.exe returned an error exitcode
Win64 - not.
Title: Re: Problem with Compare Value
Post by: trev on June 28, 2020, 05:42:27 am
No problem with macOS 10.14.6 in 32 bit or 64 bit.

Code: [Select]
$ /usr/local/lib/fpc/3.0.4/ppc386 program.pas
Free Pascal Compiler version 3.0.4 [2018/09/30] for i386
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Darwin for i386
Compiling program.pas
program.pas(8,3) Note: Local variable "B" is assigned but never used
Assembling (pipe) program.s
Linking program
ld: warning: The i386 architecture is deprecated for macOS (remove from the Xcode build setting: ARCHS)
11 lines compiled, 0.2 sec
1 note(s) issued

Code: [Select]
$ /usr/local/lib/fpc/3.0.4/ppcx64 program.pas
Free Pascal Compiler version 3.0.4 [2018/09/30] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Darwin for x86_64
Compiling program.pas
program.pas(8,3) Note: Local variable "B" is assigned but never used
Assembling (pipe) program.s
Linking program
11 lines compiled, 0.1 sec
1 note(s) issued
Title: Re: Problem with Compare Value
Post by: trev on June 28, 2020, 07:34:27 am
...\fpc\3.0.4\bin\i386-win32\fpc.exe "...\project1.lpr"
Free Pascal Compiler version 3.0.4 [2020/04/11] for i386
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win32 for i386

Quote
...\fpc\3.0.4\bin\x86_64-win64\fpc.exe "...\project1.lpr"
Free Pascal Compiler version 3.0.4 [2020/04/11] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win64 for x64

From the above I noticed that your FPC 3.0.4 compilers are dated 2020/04/11, whereas mine are 2018/09/30.

A while ago someone else was having an issue and I noticed a similar date discrepancy - when they used the "official" builds, their inexplicable problems went away.
Title: Re: Problem with Compare Value
Post by: ASerge on June 28, 2020, 08:19:40 am
From the above I noticed that your FPC 3.0.4 compilers are dated 2020/04/11, whereas mine are 2018/09/30.
A while ago someone else was having an issue and I noticed a similar date discrepancy - when they used the "official" builds, their inexplicable problems went away.
This is also the official version, only in the delivery of Lazarus 2.0.8 (just from April 2020).
Title: Re: Problem with Compare Value
Post by: Thaddy on June 28, 2020, 09:12:06 am
@ASerge
I hope you agree it would still be better to have an explicit overload for currency.
That does  not break already working platforms and fixes all others.
Title: Re: Problem with Compare Value
Post by: ASerge on June 28, 2020, 10:25:45 am
I hope you agree it would still be better to have an explicit overload for currency.
Yes, but only Win64 needs it, as I understand it.
Title: Re: Problem with Compare Value
Post by: Thaddy on June 28, 2020, 02:25:03 pm
Yes, but only Win64 needs it, as I understand it.
No. my raspberry pies needed it too (32 bit arm). As I wrote I could easily reproduce the issue. I am mostly working on those, not Windows.
But PascalDragon has solved the issue in a different way in trunk (tested 3.3.1-r45707)
My code has still value for those that do not use trunk, simply copy in the code from my example.
Title: Re: Problem with Compare Value
Post by: jamie on June 28, 2020, 02:25:13 pm
The added overload should be applicable to both because you do not want the compiler converting a currency over to a float to perform that operation. This defeats the whole reason why there Is a currency that uses the Int64 as the storage media.

 If you cast the currency to a Int64 the results are accurate for a compare of that nature, I always attempt to keep the float operations far away from it.


 I haven't checked the 32 bit port and I can't say which one gets currently called but if the compiler is calling a float operations, there by converting to a float from a currency then I really don't think that is the proper way to do it.

 I use currency types for fixed point math just to stay far away from floats to avoid the well known issues with floats

 That's my 2 cents worth and these days it seems it's not worth much.

Title: Re: Problem with Compare Value
Post by: Thaddy on June 28, 2020, 03:24:05 pm
Yes, I agree, basically you are right: a currency type should be derived from integer and scaled, but in FPC it is mapped to float types on some platforms.

Sven fixed the mapping to floats in trunk and they now work, but just in case you can use my solution on older versions of the compiler.
Title: Re: Problem with Compare Value
Post by: winni on June 28, 2020, 04:02:28 pm
Hi!

The type currency is nothing but an Int64.
The last 4 digits are the fractional part.

So the range of the currency is from MaxInt64 / 10000 downto  -MaxInt64/10000

Winni
Title: Re: Problem with Compare Value
Post by: Thaddy on June 28, 2020, 04:20:07 pm
winni, correct (it is a scaled int64) but that is not how it is implemented.
It is converted to floats... see the sources.
Title: Re: Problem with Compare Value
Post by: PascalDragon on June 28, 2020, 04:20:23 pm
The type currency is nothing but an Int64.

Not correct on i8086, i386 and x86_64 except Win64. There it is - like Comp - handled as a floating point type.
Title: Re: Problem with Compare Value
Post by: Thaddy on June 28, 2020, 04:37:35 pm
The type currency is nothing but an Int64.

Not correct on i8086, i386 and x86_64 except Win64. There it is - like Comp - handled as a floating point type.
Which is technically correct? ::) Unlike comp, currency is a well defined type....
e.g. https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/currency-data-type

whereas comp is a strictly Pascal type.
But I am happy with your fix, btw.
Title: Re: Problem with Compare Value
Post by: winni on June 28, 2020, 06:00:03 pm
@Thaddy & @PascalDragon

Sorry - my old Delphi knowledge was partly wrong.
Something learned today.

So Currency is another "Great Pretender" ...

Winni
Title: Re: Problem with Compare Value
Post by: jamie on June 28, 2020, 10:23:28 pm
Its still stored as a int64 and you can still code it has such...

for simple compares I have no idea why it does a Finteger load from an integer to generate a double and then perform the compare, it's kind of stupid really...

 You can cast the compare to a int64 and it works as a Int64 which comes out with the same answer or an answer I would trust better.

 most likely much faster in code too.


 Result := Int64(C1)-Int64(C2);

 Then test it it.
Title: Re: Problem with Compare Value
Post by: PascalDragon on June 29, 2020, 09:31:56 am
for simple compares I have no idea why it does a Finteger load from an integer to generate a double and then perform the compare, it's kind of stupid really...

Because that is how Currency is defined in both FPC and Delphi.
TinyPortal © 2005-2018