![]() |
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:
Die _ArcCsc meckert, dass die Ergebnisse nicht übereinstimmen, obwohl beide verglichenen
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; 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? |
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? |
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:
Der Unterschied zwischen obigen Mathe-Units liegt bei mir zwischen
WriteLn('Differenz = ', Math.ArcCsc(X) - JclMath.ArcCsc(X));
-2.71050543121376E-0020 … 5.42101086242752E-0020 Die von Dir angegebene
Delphi-Quellcode:
ist für Real-Zahl-Arithmetik ist „lasch“. Selbst Math.SameValue(..) verwendet einen viel geringeren Wert.
PrecisionTolerance: Float = 0.0000001;
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 |
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? |
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 |
AW: Jcl Unit test: Mathefrage
Hier das Zahlenbeispiel:
Not equals for x = -3,98, expected: <-0,253977954770906> but was: <0,253977954770906> |
AW: Jcl Unit test: Mathefrage
Hallo,
für dein Beispiel
Delphi-Quellcode:
sehen meine Ergebnisse wie folgt aus:
x:= -3.98;
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 |
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.
|
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; |
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 09:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz