Warning: Undefined array key "DOKU_PREFS" in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/common.php on line 2082
math_decimal [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


math_decimal

Warning: Undefined array key -1 in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/html.php on line 1458

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
math_decimal [2009/05/14 09:51]
tyrtamos
math_decimal [2010/03/15 06:55]
tyrtamos
Ligne 36: Ligne 36:
  
 \\ \\
-Dernier point général, les codes qui suivent supposent:+Dernier point général, **les codes qui suivent supposent**:
  
   * l'importation du module "decimal" avec "from decimal import *"   * l'importation du module "decimal" avec "from decimal import *"
Ligne 42: Ligne 42:
   * que les calculs se feront avec la précision donnée par "getcontext().prec=nbc" (nbc=nb de chiffres significatifs, 28 par défaut)   * que les calculs se feront avec la précision donnée par "getcontext().prec=nbc" (nbc=nb de chiffres significatifs, 28 par défaut)
  
-  * que les divisions avec '/' seront décimales, ce qui, avec Python 2.5, nécessite la ligne "from __future__ import division" juste après le shebang.+  * que les divisions avec '/' seront décimales, ce qui, avec Python 2.6, nécessite la ligne %%"from __future__ import division"%% juste après le shebang.
  
 ===== Calcul de sinus(x) ===== ===== Calcul de sinus(x) =====
Ligne 241: Ligne 241:
   * termes suivants: <m>terme(n) = {terme(n-1)}*{{x^2(2n-1)(2n-1)}/{(2n)(2n+1)}}</m>   * termes suivants: <m>terme(n) = {terme(n-1)}*{{x^2(2n-1)(2n-1)}/{(2n)(2n+1)}}</m>
  
-Voilà le code. Au départ, la 1ère fonction "_asindec(x)" aurait du suffire, mais elle a des problèmes de convergence lorsqu'on s'approche de x=1. Alors, on restreint ce calcul pour des valeurs de abs(x) inférieures à 0.70710678118654752 (en fait, la valeur exacte importe peu), c'est à dire pour un angle d'environ pi/4. Quand on sort de cette plage, on calcule en fait l'arc cosinus et on corrige ensuite l'angle obtenu avec pi/2.+Voilà le code. Au départ, la 1ère fonction "_asindec(x)" aurait du suffire, mais elle a des problèmes de convergence lorsqu'on s'approche de x=1. Alors, on restreint ce calcul pour des valeurs de abs(x) inférieures à 0.70710678118654752 (en fait, la valeur exacte importe peu), c'est à dire pour un angle d'environ pi/4. Quand on sort de cette plage, on calcule en fait l'arc cosinus et on corrige ensuite l'angle obtenu avec pi/2. Bien entendu, le 'pi' utilisé doit avoir la même précision que les autres nombres: voir calcul de pi plus loin dans cette page.
  
 Notez qu'on utilise la fonction racine sqrtdec(x) définie par ailleurs sur cette page. Notez qu'on utilise la fonction racine sqrtdec(x) définie par ailleurs sur cette page.
Ligne 583: Ligne 583:
  
 Simple, non? Simple, non?
 +
 +On peut, bien entendu faire une fonction spéciale et autonome intégrant l'algorithme de l'arc sinus:
 +
 +<code python>
 +def pidec():
 +    """Calcul de pi avec la précision courante (méthode avec arc sinus)"""
 +    getcontext().prec += 2
 +    x = Decimal("0.5")
 +    xc = x*x
 +    k = x
 +    s1 = k
 +    n = 0
 +    while True:
 +        n += 1
 +        k *= xc*(2*n-1)*(2*n-1)/(2*n*(2*n+1))
 +        s2 = s1 + k
 +        if s2 == s1:
 +            break
 +        s1 = s2
 +    getcontext().prec -= 2
 +    return 6*s2
 +</code>
  
 Exemple: Exemple:
Ligne 599: Ligne 621:
  
 <code python> <code python>
-pi = Decimal("+pi = Decimal("3.\ 
-3.141592653589793238462643383279502884197169399375+14159265358979323846264338327950288419716939937510
-10582097494459230781640628620899862803482534211706+58209749445923078164062862089986280348253421170679
-79821480865132823066470938446095505822317253594081+82148086513282306647093844609550582231725359408128
-28481117450284102701938521105559644622948954930381+48111745028410270193852110555964462294895493038196
-96442881097566593344612847564823378678316527120190+44288109756659334461284756482337867831652712019091
-91456485669234603486104543266482133936072602491412+45648566923460348610454326648213393607260249141273
-73724587006606315588174881520920962829254091715364+72458700660631558817488152092096282925409171536436
-36789259036001133053054882046652138414695194151160+78925903600113305305488204665213841469519415116094
-94330572703657595919530921861173819326117931051185+33057270365759591953092186117381932611793105118548
-48074462379962749567351885752724891227938183011949+07446237996274956735188575272489122793818301194912
-12983367336244065664308602139494639522473719070217+98336733624406566430860213949463952247371907021798
-98609437027705392171762931767523846748184676694051+60943702770539217176293176752384674818467669405132
-32000568127145263560827785771342757789609173637178+00056812714526356082778577134275778960917363717872
-72146844090122495343014654958537105079227968925892+14684409012249534301465495853710507922796892589235
-35420199561121290219608640344181598136297747713099+42019956112129021960864034418159813629774771309960
-60518707211349999998372978049951059731732816096318+51870721134999999837297804995105973173281609631859
-59502445945534690830264252230825334468503526193118+50244594553469083026425223082533446850352619311881
-81710100031378387528865875332083814206171776691473+71010003137838752886587533208381420617177669147303
-03598253490428755468731159562863882353787593751957+59825349042875546873115956286388235378759375195778
-78185778053217122680661300192787661119590921642019+18577805321712268066130019278766111959092164201989")
-89")+
 </code> </code>
 +
 +Si on veut calculer Pi plus rapidement et/ou avec plus de chiffres, on peut utiliser l'un des nombreux algorithmes que les fanas de Pi ont élaboré depuis toujours.
 +
 +Par exemple, avec l'algorithme de Salamin et Brent:
 +
 +<code python>
 +def pidec():
 +    """Calcul de pi avec la précision courante (Salamin et Brent)"""
 +    getcontext().prec += 2
 +    a1 = Decimal("1.0")
 +    b1 = Decimal("1.0")/Decimal("2.0").sqrt()
 +    p1 = Decimal("1.0")
 +    t1 = Decimal("0.25")
 +    eps = Decimal("1.0e-" + str(getcontext().prec-1))  # condition d'arrêt
 +    while True:
 +        a2 = (a1 + b1)/2
 +        b2 = (a1*b1).sqrt()
 +        p2 = 2*p1
 +        a12 = a1-a2
 +        t2 = t1-p1*a12*a12
 +        if abs(a2-b2)<eps:
 +            break
 +        else:
 +            a1, b1, p1, t1 = a2, b2, p2, t2
 +    ab = a2+b2
 +    res = (ab*ab)/(4*t2)
 +    getcontext().prec -= 2
 +    return res*1  # le *1 est pour revenir à la précision courante avec arrondi
 +</code>
 +
 +Avec cet algorithme, on peut calculer:
 +
 +  * Pi avec 1000 décimales en 0.14 secondes (au lieu de 7 secondes avec l'arc sinus)
 +
 +  * Pi avec 5000 décimales en 4 secondes
 +
 +  * Pi avec 50000 (cinquante mille) décimales en 10 minutes environ
 +
 +On retrouve, bien entendu les mêmes résultats que ici: http://www.brouty.fr/Maths/pi.html
  
 ===== Calcul de e ===== ===== Calcul de e =====
math_decimal.txt · Dernière modification: 2010/03/15 06:55 de tyrtamos