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())
4 réponses
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))...)
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
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.
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)