![]() |
AW: tan() von Single, Double, etc.
Zitat:
Zitat:
Zitat:
|
AW: tan() von Single, Double, etc.
Das mit nachträglichen Korrektur ist doch Bastelei, und jemandem, dem es auf Genauigkeit ankommt, unwürdig. Selbst bei einem Bereich von -1000..1000 wäre dann tan(89.95°) ungültig. Und ich würde mit Recht darauf hinweisen, daß das ein Bug ist.
Wie gesagt, die Gleitkomma-Arithmetik ist exakt, genau so exakt wie Integer-Arithmetik. Sorgen mach mir der schlampige Umgang von EMBA z.B. mit der Bereichsreduktion für sin, cos etc. Für Beispiele im Vergleich zu ![]()
Code:
(Machine eps for double = 2.220446049250E-016)
----------------------------------------------------------------- Test of DAMath.cos at 10000 random values in [-10.0000000000 .. 10.0000000000] RMS = 0.25, max rel = 0.91 eps at x(dbl) = -8.11413601040840E+000 = $C0203A7009000000 y(dbl) = -2.57229736666779E-001 = $BFD07673B6A2B86F y(mpf) = -2.57229736666778837208918104020787799191734279958E-1 Test of DAMath.cos at 10000 random values in [0.0000000000 .. 1000000000.0000000000] RMS = 0.24, max rel = 0.90 eps at x(dbl) = 3.09463918209076E+008 = $41B2720B6E358600 y(dbl) = -2.58174239840314E-001 = $BFD085ED3F3229E9 y(mpf) = -2.58174239840313841975953009564740744055663588700E-1 Test of DAMath.cos at 10000 random values in [1000000000.0000000000 .. 5.000000000000E+018] RMS = 0.24, max rel = 0.88 eps at x(dbl) = 6.18510209900251E+017 = $43A12AC7848E1D0B y(dbl) = 2.60040880178592E-001 = $3FD0A48280FF5DF3 y(mpf) = +2.60040880178592397382630269801769340226378199265E-1 Test of system.cos at 10000 random values in [-10.0000000000 .. 10.0000000000] RMS = 0.19, max rel = 0.55 eps at x(dbl) = 7.85423278808594E+000 = $401F6ABC00000000 y(dbl) = -2.51154108814005E-004 = $BF3075AAAF01351D y(mpf) = -2.51154108814004449238616298892359426342137631612E-4 Test of system.cos at 10000 random values in [0.0000000000 .. 1000000000.0000000000] RMS = 257703.83, max rel = 14362143.15 eps at x(dbl) = 7.73584246635437E+008 = $41C70DFABB515600 y(dbl) = 3.12296110038815E-004 = $3F347775944C00FF y(mpf) = +3.12296109042891252641009359676336492980461957722E-4 Test of system.cos at 10000 random values in [1000000000.0000000000 .. 5.000000000000E+018] RMS = 931290736633651.00, max rel = 60109746020807300.00 eps at x(dbl) = 2.46350079825587E+018 = $43C1180E763FF750 y(dbl) = 2.93392152252295E-003 = $3F6808E11F9FE142 y(mpf) = -2.37621355417792405078768037054894663841091297810E-4 |
AW: tan() von Single, Double, etc.
Zitat:
Für komplexe mathematische Geschichten würde ich auf eine externe Bibliothek setzen. Ob man wirklich den tan-Wert für bspw. 89.9999° braucht sei mal dahingestellt. Die Genauigkeit, bis wann man welche Eingangswerte behandelt muss man sich vorher überlegen. Was für Werte hast du denn? Willst du irgendwas darstellen?
Delphi-Quellcode:
const
FAKTOR = 10000; procedure Main; var I: Integer; Degree, Rad, TanResult: Double; LogMsg: string; DegArray: TArray<Integer>; begin for I := 89 * FAKTOR to 90 * FAKTOR do begin Degree := I / FAKTOR; Rad := DegToRad(Degree); TanResult := Tan(Rad); LogMsg := ''; if InRange(TanResult, -500000, 500000) then begin LogMsg := Format('Grad: %2.4f - Tan: %2.4f', [Degree, TanResult]); end else LogMsg := Format('Ungültige Eingabe für Tan(%2.4f) - Tan: %2.4f', [Degree, TanResult]) ; if LogMsg <> '' then Writeln(LogMsg); end; end; |
AW: tan() von Single, Double, etc.
@gammatester: Ich verwende derzeit in meiner SVG-Unit die trigonometrischen Funktionen von Delphi. Genutzt werden ausschließlich Extended-Werte. Die Genauigkeit überzeugt mich nicht. Verbessert AMath (nicht DAMath) desselben Autors diese Genauigkeit merklich?
|
AW: tan() von Single, Double, etc.
Zitat:
Und NEIN, du kannst 90° usw. niemals 100%ig korrekt darstellen, es sei denn du hast unendlich breite Register, ooooder eben eine Lib die bei entsprechenden Parametern gesondert vorgeht, und/oder andere Algorithmen verwendet, die sich nicht auf die integrierten Funktionen der CPU verlassen. (Die sind dann natürlich etwas langsamer in aller Regel.) |
AW: tan() von Single, Double, etc.
Zitat:
Zitat:
Zitat:
![]() |
AW: tan() von Single, Double, etc.
Zitat:
![]() |
AW: tan() von Single, Double, etc.
Zitat:
|
AW: tan() von Single, Double, etc.
Zitat:
Delphi-Quellcode:
Funktion mit Argumenten in ° ja auch nicht programmiert werden (tand ist eine de-facto Standardbezeichnung, sie zB
tand(x)
![]() ![]() ![]() ![]() Zuerst wird x modulo 360 reduziert, dann werden exakte Werte 0,+1,Inf,-1 je nach Vielfachen von 45 zurückgeliefert, der Rest (bei geschickter Reduktion ist der im Bereich -45 < x < 45) wird halt mit Pi/180 multipliziert und dann mit
Delphi-Quellcode:
weiter verarbeitet. In diesem Bereich sind selbst die Delphi-Funkionen genau genug (und es gibt keinen Pol/Infinity).
math.tan
|
AW: tan() von Single, Double, etc.
Zitat:
Kleine Anmerkung am Rande: Die Delphi Tan-Funktion wird je nach Zielplattform auf eine eigene Implementierung namens Tangent in System.pas weitergeleitet. Potentiell kommen da auf unterschiedlichen Plattformen und Prozessoren auch unterschiedliche Werte raus. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 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