web-dev-qa-db-fra.com

Définitions de sqrt, sin, cos, pow etc. en cmath

Existe-t-il des définitions de fonctions telles que sqrt(), sin(), cos(), tan(), log(), exp() (provenant de math.h/cmath)?

Je voulais juste savoir comment ils fonctionnent.

33
Patryk Czachurski

C'est une question intéressante, mais la lecture de sources de bibliothèques efficaces ne vous mènera pas très loin si vous ne connaissez pas la méthode utilisée.

Voici quelques conseils pour vous aider à comprendre les méthodes classiques. Mes informations ne sont en aucun cas exactes. Les méthodes suivantes ne sont que des méthodes classiques, des implémentations particulières peuvent utiliser d'autres méthodes.

  • Les tables de consultation sont fréquemment utilisées
  • Les fonctions trigonométriques sont souvent implémentées via l'algorithme CORDIC (sur la CPU ou avec une bibliothèque). Notez que d'habitude sinus et cosinus sont calculés ensemble, je me suis toujours demandé pourquoi la bibliothèque C standard ne fournit pas de fonction sincos.
  • Les racines carrées utilisent La méthode de Newton avec quelques astuces d'implémentation astucieuses: vous pouvez trouver quelque part sur le Web un extrait du code source de Quake avec une implémentation à couper le souffle de 1/sqrt (x).
  • Exponential et logarithmes utilisez exp (2 ^ nx) = exp (x) ^ (2 ^ n) et log2 (2 ^ nx) = n + log2 (x) pour avoir un argument proche de zéro (à un pour log) et utilisez approximation des fonctions rationnelles (généralement approximations de Padé ). Notez que cette même astuce peut vous donner des exponentielles matricielles et des logarithmes. Selon @Stephen Canon, les implémentations modernes favorisent l'expansion de Taylor par rapport à l'approximation de fonctions rationnelles où la division est beaucoup plus lente que la multiplication.
  • Les autres fonctions peuvent être déduites de celles-ci. Les implémentations peuvent fournir des routines spécialisées.
  • pow (x, y) = exp (y * log (x)), donc pow est not à utiliser lorsque y est un entier
  • hypot (x, y) = abs (x) sqrt (1 + (y/x) ^ 2) si x> y (hypot (y, x) sinon) pour éviter tout débordement. atan2 est calculé avec un appel à sincos et un peu de logique. Ces fonctions sont les blocs de construction de l'arithmétique complexe.
  • Pour d'autres fonctions transcendantales (gamma, erf, bessel, ...), veuillez consulter l'excellent livre Recettes numériques, 3ème édition pour quelques idées. The good'old Abramowitz & Stegun est également utile. Une nouvelle version est disponible sur http://dlmf.nist.gov/ .
  • Des techniques telles que l'approximation de Chebyshev, l'expansion continue des fractions (en fait, les approximations de Padé) ou l'économie de la série de puissances sont utilisées dans des fonctions plus complexes (par exemple, si vous lisez le code source pour erf, bessel ou gamma). Je doute qu'ils aient une utilité réelle dans les fonctions mathématiques simples en métal nu, mais qui sait. Consultez Recettes numériques pour un aperçu.
63
Alexandre C.

Chaque implémentation peut être différente, mais vous pouvez extraire une implémentation du code source de glibc (la bibliothèque GNU C).

edit: Google Code Search a été mis hors ligne, donc mon ancien lien n'allait nulle part.

Les sources de la bibliothèque mathématique de glibc se trouvent ici:

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

21
wkl

Regardez comment glibc implémente diverses fonctions mathématiques, pleines de magie, d'approximation et d'assemblage.

7
ismail

Jetez un coup d'œil aux sources fdlibm . Ils sont sympas parce que la bibliothèque fdlibm est autonome, chaque fonction est bien documentée avec des explications détaillées sur les mathématiques impliquées, et le code est extrêmement clair à lire.

5
Daniel Trebbien

Ayant beaucoup étudié le code mathématique, je vous déconseille de regarder glibc - le code est souvent très difficile à suivre et dépend beaucoup de la magie de la glibc. Le math lib dans FreeBSD est beaucoup plus facile à lire, même si parfois plus lent (mais pas beaucoup).

Pour les fonctions complexes, la principale difficulté réside dans les cas-frontière - une manipulation correcte du nan/inf/0 est déjà difficile pour des fonctions réelles, mais c’est un cauchemar pour des fonctions complexes. La norme C99 définit de nombreux cas de coin, certaines fonctions ont facilement 10 ou 20 cas de coin. Vous pouvez consulter l'annexe G du document standard à jour C99 pour vous faire une idée. Il y a aussi une difficulté avec long double, car son format n’est pas normalisé - selon mon expérience, vous devriez vous attendre à pas mal de bugs avec long double. Espérons que la prochaine version révisée de IEEE754, avec une précision accrue, améliorera la situation.

4
David Cournapeau

La plupart des matériels modernes incluent des unités à virgule flottante qui implémentent ces fonctions de manière très efficace.

0
David Heffernan