Function Min mit Currency-Werten in der 64 Bit Win-Version

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Benutzeravatar
Ally
Beiträge: 263
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von Ally »

Hallo zusammen,

bisher habe ich mit der 32 Bit Version von Lazarus unter Windows gearbeitet. Mit der 64 Bit Version und einem vorhandenen Projekt bin ich auf folgendes Problem gestoßen.

Code: Alles auswählen

{Result, Wert1 und Wert2 sind vom Typ Currency.}
 
Result := Min(Wert1, Wert2);
 
{erzeugt den Fehler: Error: Can't determine which overloaded function to call}


Für Min mit Currency-Werten ist weder in der 32 Bit Version noch in der 64 Bit Version eine Funktion vorhanden.
Warum funktioniert es in der 32 Bit Version?
Und warum gibt es für Min keine Currency-Version?

Gruß Roland

Horst_h
Beiträge: 72
Registriert: Mi 20. Mär 2013, 08:57

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von Horst_h »

Hallo,

http://www.delphibasics.co.uk/RTL.asp?Name=Currency
also scheint currency ( 53 bit Mantisse ) ein double-Wert zu sein.
Behelfsmässig

Code: Alles auswählen

program Project1;
uses
  math;
var
  Wert1,Wert2:currency;
 
function Min(val1,val2:currency):currency;overload;inline;
begin
  result := MIN(double(val1),double(val2));
end;
 
begin
  Wert1:= 1.004451;//1.00445 funktioniert nicht :-(
  Wert2:= 1.00444
  writeln('Wert1 ',Wert1);
  writeln('Wert2 ',Wert2);
  writeln(min(Wert1,Wert2));
  writeln(min(Wert2,Wert1));
end.

Ausgabe:

Code: Alles auswählen

 
Wert1  1.004500000000000000E+00
Wert2  1.004400000000000000E+00
 1.004400000000000000E+00
 1.004400000000000000E+00
 

Gruß Horst

Benutzeravatar
Ally
Beiträge: 263
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von Ally »

Hallo Horst,

danke für deine Antwort.
Ich habe mir einfach folgendes gebastelt:

Code: Alles auswählen

function MinCurrency(a, b: Currency): Currency;
begin
  if a < b then
    Result := a
  else
    Result := b;
end;


Das funktioniert auch einwandfrei.

Aber nochmal zu meiner Frage, warum funktioniert es in der 32 Bit Version?
Und warum gibt es für Min keine Currency-Version in Math?
Vielleicht liest ja hier jemand mit der das mal einbauen kann oder jemanden kennt der da kompetent ist.

Gruß Roland

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von wp_xyz »

Horst_h hat geschrieben:http://www.delphibasics.co.uk/RTL.asp?Name=Currency
also scheint currency ( 53 bit Mantisse ) ein double-Wert zu sein.

Da ist m.E. falsch. Wenn du dir die Wertebereiche von Int64 und Currency ansiehst (http://wiki.lazarus.freepascal.org/Data ... tete_Typen), dann erkennst du, dass beide dieselbe Ziffernabfolge haben, nur ist 4 Stellen von rechts ein Komma eingeschoben. D.h. Currency hat intern dieselbe Darstellung wie der Int64, der mit 10000 multipliziert worden ist. Aus diesem Grund sind Currency-Vergleiche problemlos möglich, Single-, Double- bzw. Extended-Vergleiche schlagen dagegen regelmäßig wegen Rundungsfehlern fehl.

Warum es die Funktion Min für Currency unter 64-Bit nicht gibt, weiß ich nicht. Ich vermute etwas triviales, wie "vergessen zu implementieren".

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von m.fuchs »

Welche Lazarusversion nutzt du denn? Ich hatte kein Problem Currency und Min einzusetzen mit 1.8.2 Linux x64.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von Socke »

Dann verweist doch direkt auf die offizielle Dokumentation: https://www.freepascal.org/docs-html/cu ... 300003.1.2

Ally hat geschrieben:Aber nochmal zu meiner Frage, warum funktioniert es in der 32 Bit Version?
Und warum gibt es für Min keine Currency-Version in Math?
Vielleicht liest ja hier jemand mit der das mal einbauen kann oder jemanden kennt der da kompetent ist.

Erstelle hierzu bitte einen Bug-Report unter http://bugs.freepascal.org/
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
Ally
Beiträge: 263
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von Ally »

Hallo wp_xyz,

die Variante "vergessen zu implementieren" halte ich auch für sehr wahrscheinlich, zumal die andern Typen von Integer bis Extended vorhanden sind. Lediglich Cardinal wurde, mit der Begründung "this causes more trouble than it solves", auskommentiert.


Hallo m.fuchs,

ich habe hier Lazarus 1.8.2/ FPC 3.0.4 - 64 Bit Windows und Lazarus 1.8.2/ FPC 3.0.4 - 32 Bit Windows.
Beide laufen auf je einem Rechner mit Windows 10 - 64 Bit.


Hallo Socke,

das mit dem Bug-Report gehört jetzt nicht gerade zu meinen Kernkompetenzen, vielleicht könntest du das ja übernehmen. :roll:


Gruß Roland

Horst_h
Beiträge: 72
Registriert: Mi 20. Mär 2013, 08:57

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von Horst_h »

Hallo,

Apropos:
D.h. Currency hat intern dieselbe Darstellung wie der Int64

Ich bezog mich auf die Angabe bei DelphiBasics.53 Bit Mantisse ist double.
Delphi <> FPC
Int64 war schon seit Turbo-Pascal ?.? üblich.
Wenn man in den Kompilerquelltext unter rtl/inc/gencurr.inc schaut steht dort
{$ifdef FPC_CURRENCY_IS_INT64}

Es gibt wohlmöglich auch eine { zukünftig } andere Version davon.

Gruß Horst

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Function Min mit Currency-Werten in der 64 Bit Win-Versi

Beitrag von Socke »

Horst_h hat geschrieben:Wenn man in den Kompilerquelltext unter rtl/inc/gencurr.inc schaut steht dort
{$ifdef FPC_CURRENCY_IS_INT64}

Es gibt wohlmöglich auch eine { zukünftig } andere Version davon.

Aktuell gibt es AFAIK keine andere Version. Es ist nur ein übliches Vorgehen um weitere Versionen schnell und ohne Effekte auf die bisherigen Implementierungen einbauen zu können.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Locast
Beiträge: 2
Registriert: Fr 11. Dez 2020, 16:22

Re: Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von Locast »

Hallo zusammen,

ich bin mit der Suche nach "gencurr.inc" auf diesen Thread gestoßen und habe vielleicht ein ähnliches Problem.

Ich arbeite mit der Lazarus Version 2.0.10 64-bit und habe versucht, einen 5 Jahre alten Quellcode zu compilieren, welchen ich damals noch erfolgreich mit der 32-Bit-Version compilieren konnte.

Jetzt erscheint aber ein mir unerklärlicher Fehler bei den folgenden Zeilen:
dX := round(dX * FeldGr);
dY := round(dY * FeldGr);
Dabei sind dX und dY lokale Variablen vom Typ word und FeldGr eine globale Variable vom Typ byte.

Folgende Fehlermeldung erscheint:
Error: Can't determine which overload function to call
gencurr.inc (55,14) Hint: Found declaration: Round (Comp):Int64
gencurr.inc (33,14) Hint: Found declaration: Round (Currency):Int64
Klicke ich auf die Fehlermeldung dann erscheint:
Kann die Datei "gencurr.inc" nicht finden.
...
Habe ich jetzt eher ein Problem mit der Installation von Lazarus oder habe ich die Funktion round mit einem falschen Datentyp aufgerufen?
Kann jemand helfen?

Sieben
Beiträge: 202
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von Sieben »

Mal so gefragt: was gibt's denn bei einem Produkt von word und byte zu runden...? Sind doch beides Ganzzahlen.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von Winni »

Round vom word x byte ist völlig sinnlos.
Aber jeder darf doch seinen code so langsam machen, wie er möchte.

Natürlich gibt es ein min für curreny.

Code: Alles auswählen

WenigKohle :=  math.min (Dollar,Euro);
Der skurile Definitionsweg von currency geht so:

Code: Alles auswählen

Type
currency = extended;
Da es auf 64-Bit-Systemen auf dem Processor kein extended gibt ist dort
definiert:

Code: Alles auswählen

extended = double;
So dass im Endeffekt auf 64 Bit Systemen mit Double gerechnet wird.
Auf 32-Bittern hingegen mit 80 Bit.
Hier gibt's was zu lesen - viele Spachen, aber nix deutsch:

https://wiki.freepascal.org/Currency


Winni

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von wp_xyz »

Im Zweifelsfall glaube ich da eher der offiziellen Dokumentation https://www.freepascal.org/docs-html/ref/refsu5.html:
The currency type is a fixed-point real data type which is internally used as an 64-bit integer type (automatically scaled with a factor 10000), this minimizes rounding errors.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von Winni »

wp_xyz hat geschrieben:
Fr 11. Dez 2020, 19:38
Im Zweifelsfall glaube ich da eher der offiziellen Dokumentation https://www.freepascal.org/docs-html/ref/refsu5.html:
The currency type is a fixed-point real data type which is internally used as an 64-bit integer type (automatically scaled with a factor 10000), this minimizes rounding errors.



Für Glauben ist de Kirche zuständig. Oder Baghwahn.

Ja - erstens scheinen die Dokumentierenden den Type curreny auch nur teilweise kapiert zu haben.
Und zweitens steigt die Faulheit, den 32-Bit-Teil gleich mal wegzulassen.

Und drittens: wieso wiederspricht die Doku meinen Aussagen?

Intern wird nur mit Hilfe von 64-Bit-Integers darauf geachtet, dass nach dem Komma nicht mehr als vier Stellen auftauchen. Es kann natürlich bei Fliesskommazahlen passieren, dass das Komma zu weit "nach vorne" rutscht - z.B. bei Division. Hier wird mittels der der 64 Bit Integers drauf geachtet, dass nur 4 Stellen nach dem Komma vorhanden sind - falls mehr wird gerundet.

Und außerdem gibt es noch der Check, ob der Wert sich noch im definierten Wert-Bereich befindet.
Das war (aus dem Kopf ) so um -9*10^14 ... +9*10^14
Mehr so für Amazon und Google.

Winni

Locast
Beiträge: 2
Registriert: Fr 11. Dez 2020, 16:22

Re: Function Min mit Currency-Werten in der 64 Bit Win-Version

Beitrag von Locast »

Mal so gefragt: was gibt's denn bei einem Produkt von word und byte zu runden...? Sind doch beides Ganzzahlen.
Ja, nachdem der Post eine Weile gepostet war und ich in Ruhe vor dem Fernseher gesessen bin, kam mir auch der Gedanke, dass das Produkt aus zwei ganzzahligen Zahlen ebenfalls ganzzahlig sein muss.
Warum hatte ich das damals mit round gemacht? Wahrscheinlich weil der * Operator auch für nicht ganzzahlige Zahlen verwendet werden kann und ich mir nicht sicher war, welchen Datentyp er zurückgibt.

Kurzum, ich hab das round rausgeschmissen und jetzt kompiliert es und läuft doppelt so schnell wie vorher.

Antworten