web-dev-qa-db-fra.com

OverflowError: (34, 'Résultat trop important')

Je reçois une erreur de débordement (OverflowError: (34, 'Résultat trop important')
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
user3033766

Les flotteurs Python ne sont ni une précision arbitraire ni une taille illimitée. Lorsque 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))...)
20
Peter DeGlopper

Vous avez atteint les limites du support float de votre plate-forme, probablement après le 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 pour les limitations exactes, mais il est peu probable que vous rencontriez une combinaison actuelle de processeur et de système d'exploitation qui vous donnera 100 chiffres significatifs dans tous les cas. Mon MacBook Pro avec OS X 64 bits ne prend en charge que 15 ordinateurs.

Utilisez le module decimal pour dépasser les limitations de votre matériel.

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 
14
Martijn Pieters

J'utilise python3.6 AMD64, je rencontre également ce problème, car python float est une variable double précision, elle est à 64 bits, dans la plupart des tâches de programmation, 64 bits suffisent, assez (comme l'informatique scientifique, l'informatique big data) 

0
员建新

16. ** 256 est trop grand pour être stocké dans un float à double précision. Je suggère que vous exécutiez votre cycle moins cher, comme dans l'intervalle (250), car des valeurs k plus grandes ne contribueront de toute façon pas aux cent premiers chiffres.

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'erreur d'exécution.

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

0
Bence