Definitionen von sqrt, sin, cos, pow etc. in cmath

Lesezeit: 6 Minuten

Benutzeravatar von Pythagoras von Samos
Pythagoras von Samos

Gibt es Definitionen von Funktionen wie z sqrt(), sin(), cos(), tan(), log(), exp() (diese aus math.h/cmath) vorhanden ?

Ich wollte nur wissen, wie sie funktionieren.

  • fdlibm bietet Implementierungen all dieser Dinge und ist Open Source, eigenständig und ziemlich lesbar. Nicht die einfachsten möglichen Implementierungen, da sie darauf ausgelegt sind, eine anständige Leistung zu bieten.

    – Steve Jessop

    27. Dezember 2010 um 19:12 Uhr


  • mögliches Duplikat von Wie berechnet C sin() und andere mathematische Funktionen?

    – Jason Orendorff

    28. Dezember 2010 um 1:49 Uhr

Benutzeravatar von Alexandre C
Alexandre C.

Dies ist eine interessante Frage, aber das Lesen von Quellen effizienter Bibliotheken wird Sie nicht sehr weit bringen, es sei denn, Sie kennen die verwendete Methode.

Hier sind einige Hinweise, die Ihnen helfen sollen, die klassischen Methoden zu verstehen. Meine Angaben sind auf keinen Fall korrekt. Die folgenden Methoden sind nur die klassischen, bestimmte Implementierungen können andere Methoden verwenden.

  • Nachschlagetabellen werden häufig verwendet
  • Trigonometrische Funktionen werden oft über die implementiert CORDIC Algorithmus (entweder auf der CPU oder mit einer Bibliothek). Beachten Sie, dass Sinus und Cosinus normalerweise zusammen berechnet werden. Ich habe mich immer gefragt, warum die Standard-C-Bibliothek keine bietet sincos Funktion.
  • Quadratwurzel verwenden Newtons Methode mit einigen schlauen Implementierungstricks: Vielleicht finden Sie irgendwo im Web einen Auszug aus dem Quake-Quellcode mit einer umwerfenden 1 / sqrt(x)-Implementierung.
  • Exponential und Logarithmen verwenden exp(2^nx) = exp(x)^(2^n) und log2(2^nx) = n + log2(x), um ein Argument nahe Null zu haben (eins für log) und verwenden Annäherung an rationale Funktionen (normalerweise Padé-Annäherungen). Beachten Sie, dass Sie mit genau diesem Trick Matrixexponenten und Logarithmen erhalten können. Laut @Stephen Canon bevorzugen moderne Implementierungen die Taylor-Erweiterung gegenüber der Annäherung an rationale Funktionen, bei der die Division viel langsamer ist als die Multiplikation.
  • Aus diesen lassen sich die anderen Funktionen ableiten. Implementierungen können spezialisierte Routinen bereitstellen.
  • pow(x, y) = exp(y * log(x)), also ist pow nicht zu verwenden, wenn y eine ganze Zahl ist
  • hypot(x, y) = abs(x) sqrt(1 + (y/x)^2) wenn x > y (andernfalls hypot(y, x)), um einen Überlauf zu vermeiden. atan2 wird mit einem Aufruf an berechnet sincos und ein wenig Logik. Diese Funktionen sind die Bausteine ​​für komplexe Arithmetik.
  • Für andere transzendente Funktionen (Gamma, Erf, Bessel, …) konsultieren Sie bitte das ausgezeichnete Buch Numerische Rezepte, 3. Auflage für einige Ideen. Der gute Alte Abramowitz & Stegun ist auch nützlich. Es gibt eine neue Version unter http://dlmf.nist.gov/.
  • Techniken wie Chebyshev-Approximation, Kettenbrucherweiterung (eigentlich verwandt mit Padé-Approximationen) oder Potenzreihenökonomisierung werden in komplexeren Funktionen verwendet (wenn Sie beispielsweise Quellcode für erf, bessel oder gamma lesen). Ich bezweifle, dass sie einen wirklichen Nutzen in einfachen mathematischen Bare-Metal-Funktionen haben, aber wer weiß. Eine Übersicht finden Sie unter Numerical Recipes.

  • +1, um die Mathematik tatsächlich zu erklären. Ich fühlte mich viel besser, als mir klar wurde, dass trigonometrische Funktionen nur abgeschnittene Erweiterungen von Taylor-Reihen waren. Ansonsten sehen die Annäherungen wie ernsthafte Zauberei aus!

    – Ben Jackson

    27. Dezember 2010 um 20:27 Uhr

  • @Ben: Gute Bibliotheken verwenden normalerweise keine abgeschnittenen Taylor-Reihen – andere Polynomnäherungen (Minimax, Chebyshev, Padé) haben viel wünschenswertere Fehlereigenschaften und ermöglichen es, mit weniger arithmetischen Operationen die gleiche Genauigkeit zu erzielen.

    – Stefan Kanon

    27. Dezember 2010 um 23:45 Uhr

  • @Alexandre: rationale Annäherung ist meistens aus der Mode gekommen für exp und log weil Multiplikation und Addition auf moderner Hardware so viel schneller sind als Division. Es wird jedoch immer noch für steifere Funktionen verwendet.

    – Stefan Kanon

    27. Dezember 2010 um 23:46 Uhr

  • Abramowitz & Stegun ist der umgangssprachliche Name der NIST-Veröffentlichung „Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables“ von 1964. Bitte verlinken Sie auf die Ausgabe 2010 „NIST Digital Library of Mathematical Functions“, frei verfügbar online unter dlmf.nist.gov

    – Janus

    28. Dezember 2010 um 3:48 Uhr


  • @Janus “Der” Abramowitz ist so ein Klassiker … Ich habe fast ein paar Tränen vergossen, weil ich ihn in SO zitiert habe …

    – Dr. belisarius

    28. Dezember 2010 um 4:39 Uhr

Benutzeravatar von wkl
wkl

Jede Implementierung kann anders sein, aber Sie können eine Implementierung aus dem Quellcode von glibc (der GNU C-Bibliothek) auschecken.

Bearbeiten: Google Code Search wurde offline genommen, daher geht der alte Link, den ich hatte, nirgendwo hin.

Die Quellen für die mathematische Bibliothek von glibc befinden sich hier:

http://sourceware.org/git/?p=glibc.git;a=tree;f=math;h=3d5233a292f12cd9e9b9c67c3a114c64564d72ab;hb=HEAD

Schauen Sie sich an, wie glibc implementiert verschiedene mathematische Funktionen, voller Magie, Annäherung und Assemblierung.

  • +1 für den Glibc-Sourceware-Link, aber wow, die Seite ist gerade langsam. (bearbeitet)

    – Wo

    27. Dezember 2010 um 19:19 Uhr


  • Afaik sind dies die langsamen Versionen mit schnelleren Implementierungen in Arch. bestimmte Unterordner.

    – ismail

    27. Dezember 2010 um 19:21 Uhr

  • LOL, das Internet ist immer langsam, hier kann ich keinen Unterschied feststellen 😉

    – ismail

    27. Dezember 2010 um 19:24 Uhr

Schaut euch unbedingt die an fdlibm Quellen. Sie sind nett, weil die fdlibm-Bibliothek in sich abgeschlossen ist, jede Funktion mit detaillierten Erklärungen der beteiligten Mathematik gut dokumentiert ist und der Code immens klar zu lesen ist.

Nachdem ich mich viel mit mathematischem Code beschäftigt habe, würde ich davon abraten, glibc zu betrachten – der Code ist oft ziemlich schwer zu befolgen und hängt stark von der glibc-Magie ab. Das Mathebibliothek in FreeBSD ist viel einfacher zu lesen, wenn auch manchmal langsamer (aber nicht viel).

Bei komplexen Funktionen liegt die Hauptschwierigkeit in Grenzfällen – die korrekte Handhabung von nan/inf/0 ist bereits für echte Funktionen schwierig, aber für komplexe Funktionen ein Albtraum. Der C99-Standard definiert viele Eckfälle, einige Funktionen haben leicht 10-20 Eckfälle. Sie können den Anhang G der aktuellen Version einsehen C99-Standarddokument um eine Vorstellung zu bekommen. Es gibt auch eine Schwierigkeit mit Long Double, da sein Format nicht standardisiert ist – meiner Erfahrung nach sollten Sie mit Long Double einige Fehler erwarten. Hoffentlich wird die kommende überarbeitete Version von IEEE754 mit erweiterter Präzision die Situation verbessern.

  • Guter Punkt mit den Eckfällen. Sie können in einigen Fällen leicht zu Engpässen werden (die Implementierung von ldexp auf MSVC macht die Funktion zum Beispiel ziemlich nutzlos)

    – Alexander C.

    5. Januar 2012 um 19:53 Uhr

Benutzeravatar von David Heffernan
David Heffernan

Die meisten modernen Hardwarekomponenten enthalten Gleitkommaeinheiten, die diese Funktionen sehr effizient implementieren.

  • Guter Punkt mit den Eckfällen. Sie können in einigen Fällen leicht zu Engpässen werden (die Implementierung von ldexp auf MSVC macht die Funktion zum Beispiel ziemlich nutzlos)

    – Alexander C.

    5. Januar 2012 um 19:53 Uhr

Verwendungszweck: Wurzel(Zahl,Wurzel,Tiefe)

Beispiel: root(16,2) == sqrt(16) == 4
Beispiel: root(16,2,2) == sqrt(sqrt(16)) == 2
Beispiel: root(64,3) == 4

Implementierung in C#:

double root(double number, double root, double depth = 1f)
{
    return Math.Pow(number, Math.Pow(root, -depth));
}

Verwendungszweck: Sqrt(Zahl,Tiefe)

Beispiel: Quadrat(16) == 4
Beispiel: Quadrat(8,2) == Quadrat(Quadrat(8))

double Sqrt(double number, double depth = 1) return root(number,2,depth);

Durch: Imk0tter

  • Willkommen bei SO, bitte lesen Sie hier nach, um Ihre Frage/Antwort besser zu präsentieren: meta.stackoverflow.com/a/251362/3519504

    – Sandeep Kumar

    9. Mai 2020 um 22:41 Uhr

1392150cookie-checkDefinitionen von sqrt, sin, cos, pow etc. in cmath

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy