Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Jcl Unit test: Mathefrage (https://www.delphipraxis.net/205162-jcl-unit-test-mathefrage.html)

TurboMagic 7. Aug 2020 08:48

Jcl Unit test: Mathefrage
 
Damit es nicht untergeht dachte ich, ich lagere diese gestern gestellte Frage mal in einen
neuen Thread aus:

In TestJclMath sind einige leere Testmethoden schon mal deklariert, aber noch nicht ausprogrammiert.
Manche davon konnte ich inzwischen ausfüllen (Pull requests sind erstellt), aber diese hier Will
nicht so recht, dummerwise bin ich aber auch kein Mathe-Genie:

Delphi-Quellcode:
procedure TMathTranscendentalTest._ArcCsc;
var
  x: Extended;

begin
  x := -3.98;

  while x < -1 do
  begin
    CheckEquals(Math.ArcCsc(X), JclMath.ArcCsc(X), PrecisionTolerance);
    x := x + 0.1;
  end;

  x := 1.00;

  while x < 4 do
  begin
    CheckEquals(Math.ArcCsc(X), JclMath.ArcCsc(X), PrecisionTolerance);
    x := x + 0.1;
  end;
end;
Die _ArcCsc meckert, dass die Ergebnisse nicht übereinstimmen, obwohl beide verglichenen
Ergebnisse lt. DUnit log-Eintrag identisch sind. Da muss wohl der Fehler noch weiter hinten
in den Nachkommastellen liegen...

PrecisionTolerance: Float = 0.0000001;
Und Log-Meldung: expected: <-0,253977954770906> but was: <0,253977954770906>

Habe jetzt eben erst gesehen, dass das Vorzeichen falsch ist und ein Vergleich von Math.ArcCsc und JclMath.ArcCSc ergibt:
System.Math: Result := ArcSin(1 / X);
JclMath: Result := ArcSec(X / Sqrt(X * X -1));

Wer hat recht?

TurboMagic 7. Aug 2020 08:49

AW: Jcl Unit test: Mathefrage
 
Und weil wir gerade beim Thema Mathe sind:

Und ArcSec Test der analog zum ArcCsc von mir umgesetzt wurde läuft auch auf einen Fehler und hier
wird das auch in System.Math und JclMath unterschiedlich implementiert, wobei JclMath sogar die
Implementation von System.Math benutzt, wenn ein gewisses Define gesetzt ist.

JclMath: FArcTan(Sqrt(X*X - 1)); aber in ASM programmiert
System.Math: Result := ArcCos(1 / X);

Warum ist die Umsetzung in der JCL so anders?
Was tun?

Andreas13 7. Aug 2020 10:19

AW: Jcl Unit test: Mathefrage
 
Hallo TurboMagic,

da ich die Jcl Unit selber nicht benutze, konnte ich für Dich nur eine Gegenüberstellung zwischen der von mir präferierten hochpräzisen Mathe-Bibliothek AMath von Wolfgang Ehrhardt (Gammatester) und der Standard-Delphi-Unit Math machen.

Füg doch mal folgende Zeile in Deinen Code ein:
Delphi-Quellcode:
WriteLn('Differenz = ', Math.ArcCsc(X) - JclMath.ArcCsc(X));
Der Unterschied zwischen obigen Mathe-Units liegt bei mir zwischen
-2.71050543121376E-0020 … 5.42101086242752E-0020

Die von Dir angegebene
Delphi-Quellcode:
PrecisionTolerance: Float = 0.0000001;
ist für Real-Zahl-Arithmetik ist „lasch“. Selbst Math.SameValue(..) verwendet einen viel geringeren Wert.

Ich kann nicht beurteilen, ob JclMath besser ist als Math. Was ich definitiv weiß, AMath von unserem leider zu früh verstorbenem Gammatester liefert stets auf 19 Nachkommastellen exakte Werte.
Gruß, Andreas

TurboMagic 7. Aug 2020 10:28

AW: Jcl Unit test: Mathefrage
 
Danke schon mal für die Antwort, nur:
wenn ich für diesen Test die Toleranz auf einen noch kleineren Wert umstelle,
dann wird ja das Problem, dass die beiden Werte als ungleich angesehen werden
eher größer, oder täusche ich mich da?

Außerdem ist ja das Problem, dass ein komplett unterschiedliches Vorzeichen rauskommt.
Also eine der beiden Parteien liefert wohl das Ergebnis, aber im falschen Quadranten.
Das ist doch das Hauptproblem.

Nur wer von den beiden ist es?

Andreas13 7. Aug 2020 11:37

AW: Jcl Unit test: Mathefrage
 
Ja, natürlich: Wenn Du die Toleranz verkleinerst, wird eine noch geringere Abweichung als bedeutsam ausgewiesen. Vermutlich sind grobe Fehler in JclMath vorhanden. Könntest Du bitte den Quellcode der Implementierung der Funktion JclMath.ArcCsc(x: Extended) posten? Und Dein konkretes Zahlenbeispiel, in dem die falschen Quadranten rauskommen?
Gruß, Andreas

TurboMagic 7. Aug 2020 12:50

AW: Jcl Unit test: Mathefrage
 
Hier das Zahlenbeispiel:

Not equals for x = -3,98, expected: <-0,253977954770906> but was: <0,253977954770906>

Andreas13 7. Aug 2020 13:44

AW: Jcl Unit test: Mathefrage
 
Hallo,
für dein Beispiel
Delphi-Quellcode:
x:= -3.98;
sehen meine Ergebnisse wie folgt aus:
AMath.ArcCsc(-3.98) = -0.25397795477090606400
Math.ArcCsc(-3.98) = -0.25397795477090606400
Diff: AMath - Math = -2.71050543121376E-0020 // Fazit: intern sind sie doch unterschiedlich!

Der exakte Wert mittels Multipräzisions-Arithmetik (die ersten 50 Stellen) lautet:

ArcCsc(-3.98) exakt = -0.253977954770906064152801105213402329055852686874

Diff: Exakt - Math = -0.000000000000000000026373915071569760740558348483 8
Diff: Exakt - AMath = 0.000000000000000000000731139240567850109627971537 9

Fazit: AMath. ArcCsc(x) ist um zwei Stellen genauer als Math.ArcCsc(x).

Vergleiche mal das Ergebnis mit JclMath.ArcCsc(X). In welchem Bespiel stimmen die Quadranten nicht?
Gruß, Andreas

Andreas13 7. Aug 2020 13:51

AW: Jcl Unit test: Mathefrage
 
Wenn ich meine Zahlen mit Deinen vergleiche, habe ich den Verdacht, daß JclMath.ArcCsc(x) nur mit Double-Zahlen arbeitet, oder wenigstens zeigt CheckEquals(..) nur Double-Ergebnisse an.

Andreas13 7. Aug 2020 14:00

AW: Jcl Unit test: Mathefrage
 
Gerade fällt mir eine wichtige Frage ein: Kompilierst Du für die 32-Bit-Plattform oder für 64-Bit?
Bei 64-Bit gilt LEIDER nämlich
Delphi-Quellcode:
Type
  Extended = Double;

TurboMagic 7. Aug 2020 14:10

AW: Jcl Unit test: Mathefrage
 
Hallo,

danke schon mal für deine Mühen!

Aber:

1. das mit 64 Bit und extended = double ist mir grundsätzlich bewußt.
Das war damals der Deal, sonst gäb's unter 64 Bit keine ASM Unterstützung,
gegen die wurde das eingetauscht ;-)

2. Du hast meinen letzten Beitrag zum Thema nicht ganz richtig gelsen.
Du hast wie ich am Anfang auch übersehen, dass die eine Zahl mit - als Vorzeichen
und die andere (die von JCLMath) kein Vorzeichen hat, also positiv ist.
Der Unterschied liegt also nicht in irgendwelcher Nachkommastellen-Präzision! ;-)

Schaut man sich den Code von JCLMath und von Math an, sieht man auch, dass da ein
unterschiedliches Rechehverfahren benutzt wird.

Nach deinem Test würde ich aber sagen, dass System.Math recht hat. Oder? ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz