OverflowError: (34, "résultat trop grand")

je suis arriver une erreur de dépassement de capacité(OverflowError: (34, 'trop grand')

Je veux calculer pi à 100 décimales voici mon code:

def pi(): 
    pi = 0 
    for k in range(350): 
        pi += (4./(8.*k+1.) - 2./(8.*k+4.) - 1./(8.*k+5.) - 1./(8.*k+6.)) / 16.**k 
    return pi 
print(pi())
10
demandé sur Janne Karila 2013-11-25 23:36:51

4 réponses

Les flotteurs

Python ne sont ni de précision arbitaire ni de taille illimitée. Quand k = 349, 16.**k est beaucoup trop grand - c'est presque 2^1400. Heureusement ,la bibliothèque decimal permet une précision arbitraire et peut gérer la taille:

import decimal
decimal.getcontext().prec = 100
def pi():
    pi = decimal.Decimal(0)
    for k in range(350):
        pi += (decimal.Decimal(4)/(decimal.Decimal(8)*decimal.Decimal(k+1))...)
19
répondu Peter DeGlopper 2013-11-25 19:44:16

vous avez atteint les limites du support float de votre plateforme, probablement après k = 256 :

>>> k = 256
>>> (4./(8.*k+1.) - 2./(8.*k+4.) - 1./(8.*k+5.) - 1./(8.*k+6.)) / 16.**k
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')
>>> k = 255
>>> (4./(8.*k+1.) - 2./(8.*k+4.) - 1./(8.*k+5.) - 1./(8.*k+6.)) / 16.**k
3.19870064997e-313

Voir sys.float_info le nombre exact de limitations, mais il est rare de courir dans un actuelle du PROCESSEUR et l'OS de la combinaison qui vous donnerons 100 chiffres significatifs dans tous les cas; mon MacBook Pro 64-bit OS X ne supporte 15.

utilisez le decimal module pour aller au-delà de vos limites matérielles.

from decimal import Decimal, localcontext

def pi(): 
    with localcontext() as ctx:
        ctx.prec = 100  # 100 digits precision
        pi = Decimal(0) 
        for k in range(350): 
            pi += (Decimal(4)/(Decimal(8)*k+1) - Decimal(2)/(Decimal(8)*k+4) - Decimal(1)/(Decimal(8)*k+5) - Decimal(1)/(Decimal(8)*k+6)) / Decimal(16)**k 
    return pi 
13
répondu Martijn Pieters 2013-11-25 19:50:24

16.** 256 est trop grand pour être stocké dans un flotteur de double précision. Je suggère que vous exécutiez votre cycle pour moins, comme la portée(250), parce que les valeurs plus grandes de k ne contribueront pas aux cent premiers chiffres de toute façon.

une autre chose que vous pourriez essayer est de multiplier par 16.* (- k) au lieu de diviser par 16. * K. Ce nombre sera arrondi à zéro pour le grand k, donc ne vous donnera pas d'erreurs d'exécution.

je vous suggère d'utiliser numpy.puissance au lieu de**, il gère mieux les débordements. Par exemple, dans votre code numpy.d'alimentation(16., 256) serait évalué à inf, et la division d'un nombre fini par inf donne zéro, ce qui évite les erreurs d'exécution tout comme la méthode suggérée dans le paragraphe précédent.

0
répondu Bence 2013-11-25 19:49:13

j'utilise python3.6 AMD64, je rencontre aussi ce problème,c'est parce que python intégré float est double-précision-float,c'est 64 bits,dans la plupart des tâches de programmation,64 bits est suffisant,mais dans certaines tâches supplémentaires,il n'est pas suffisant(comme l'informatique scitifique, le calcul big data)

0
répondu 员建新 2017-06-19 07:51:23