AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

tan() von Single, Double, etc.

Ein Thema von Rollo62 · begonnen am 20. Nov 2017 · letzter Beitrag vom 22. Nov 2017
Antwort Antwort
Seite 2 von 5     12 34     Letzte » 
Medium

Registriert seit: 23. Jan 2008
3.685 Beiträge
 
Delphi 2007 Enterprise
 
#11

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 14:23
Ja, genau dehalb bezeiche ich als "Bug", denn das genaue Verhalten ist ja nicht dokumentiert und bei Single, Double, etc. auch individuell anders.
Genau genommen ist es eigentlich eine wohlbekannte und zwangsweise Folge des Rechnens mit Zahlendarstellungen nach IEEE 754. Braucht man höhere Genauigkeit als diese zusichern, muss man zu entsprechenden Libs greifen die diese Eigenschaften umschiffen.

Zitat:
Das mag sein, mir geht es aber um die Richtigkeit der Ergebnisse.
Nochmal: Die Ergebnisse sind richtig. Die Eingabe in Grad und die Nutzung von binärer Gleitkommaarithmetik verschleiern lediglich die Rundungen die auf dem Weg zum Ergebnis hin notwendigerweise passieren. Wie schon erwähnt wirst du genau genommen (und darum geht es dir ja) es niemals schaffen der tan() Funktion einen Parameter zu übergeben der korrekterweise zu NaN führt, da eben genau diese Parameter schon per Definition eine Wertigkeit haben, die kein x86 Computer der Welt (nativ) korrekt abbilden kann.

Zitat:
Das Ganze hat für mich den Geschmack von "irgendeinen Tod muss man sterben".
Das ist schon durch die Nutzung von binären Gleitkommazahlen abgemachte Sache.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#12

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 15:39
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 DAmath siehe unten. Und selbstverständlich kann man die Polstellen für tan bei 90° + k * 180° sauber darstellen, die Funktion tand in DAMath liefert allerdings Infinity statt NaN.
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
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#13

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 16:12
Das Ganze hat für mich den Geschmack von "irgendeinen Tod muss man sterben".
Die Frage ist halt auch, wie genau man es braucht? Und wofür wird es gebraucht?
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;
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.049 Beiträge
 
Delphi 2009 Professional
 
#14

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 18:29
@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?
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.685 Beiträge
 
Delphi 2007 Enterprise
 
#15

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 18:55
daß das ein Bug ist.
Dann ist es ein Bug in jeder x86/x64 CPU der Welt. Denn Delphi macht nichts anderes als deren integrierten trigonometrischen Funktionen ohne viel drumrum direkt zu nutzen. In meinen Augen KEIN Bug, sondern eine systembedingte, bekannte Designschwäche, mit der ALLE Compiler entweder leben müssen, und/oder für gehobene Ansprüche Libs einsetzen, die die Spezialfälle gezielt abdecken.

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.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#16

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 19:49
Lies noch einmal genau nach! Ich habe beschrieben:
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.
Und wenn tan(89.95°)=Nan oder Inf oder was auch immer Du als ungültig wählst, kein Bug wäre, was ist dann noch ein Bug?
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.
Das ist doch Unsinn, selbstverständlich kann 90 exakt als Double/Single darstellen, und man braucht auch keine 'unendlich breite' Register, um korrekt gerundete Werte für sin, tan etc auszurechnen. Man muß es nur wollen! Für ein frei zugängliches Beispiel zu nennen siehe http://cvsweb.openbsd.org/cgi-bin/cv.../lib/libm/src/, und nicht wie EMBA, das Problem aussitzen. Immerhin haben sie in der 64-Bit-RTL einen Schritt in die richtige Richtung gemacht und eine schon 37 Jahre junge Technik von Cody/Waite übernommen, aber den letzten Schritt woll(t)en sie nicht gehen, aus welchen Gründen auch immer (zumindest im letzten für mich vorliegen Quellcode of Delphi18/XE4).
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#17

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 19:59
@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?
Ja, und wenn Du Fragen hast, stehe ich selbstverständlich zur Verfügung. Bei den trigonometrischen extended Funktionen kommt erschwerend hinzu, daß ein viel größerer Bereich bis 2^16384 behandelt werden muss und die Reduktion mod 2*Pi entsprechend aufwendig ist. Für Vergleiche siehe die Datei t_amathx.cmp im Archiv http://www.wolfgang-ehrhardt.de/amath_2017-11-02.zip.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.425 Beiträge
 
Delphi 12 Athens
 
#18

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 22:28
Das ist doch Unsinn, selbstverständlich kann 90 exakt als Double/Single darstellen,
Dummerweise nimmt die Funktion aber keine Grad an sondern Radians. Daher werden die 90° mit einer nur begrenzt genauen Repräsentation von π multipliziert, was dann im Ergebnis eben nicht genau π/2 entspricht.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#19

AW: tan() von Single, Double, etc.

  Alt 20. Nov 2017, 23:02
Dummerweise nimmt die Funktion aber keine Grad an sondern Radians. Daher werden die 90° mit einer nur begrenzt genauen Repräsentation von π multipliziert, was dann im Ergebnis eben nicht genau π/2 entspricht.
Richtig, aber so sollte eine tand(x) Funktion mit Argumenten in ° ja auch nicht programmiert werden (tand ist eine de-facto Standardbezeichnung, sie zB Matlab, Scilab, Octave oder GNU Fortran.

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 math.tan weiter verarbeitet. In diesem Bereich sind selbst die Delphi-Funkionen genau genug (und es gibt keinen Pol/Infinity).

Geändert von gammatester (20. Nov 2017 um 23:06 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.425 Beiträge
 
Delphi 12 Athens
 
#20

AW: tan() von Single, Double, etc.

  Alt 21. Nov 2017, 00:42
Richtig, aber so sollte eine tand(x) Funktion mit Argumenten in ° ja auch nicht programmiert werden
Da zum Delphi-Sprachumfang aber nun mal keine tand-Funktion gehört (Delphi 5 kannte noch nicht einmal tan), kann man sich ja bei Bedarf was Passendes selbst programmieren. Mach doch mal einen Vorschlag so wie du es dir vorstellst.

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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:52 Uhr.
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