OverflowError: (34, 'Result too large')

I ' m getting an overflow error (OverflowError: (34, 'Result too large')
Chcę obliczyć pi do 100 miejsc po przecinku Oto Mój kod:

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())
Author: Janne Karila, 2013-11-25

5 answers

Pływaki pytona nie są ani arbiterową precyzją, ani nieograniczonymi rozmiarami. Gdy k = 349, 16.**k jest o wiele za duża - to prawie 2^1400. Na szczęście biblioteka decimal pozwala na dowolną precyzję i może obsługiwać rozmiar:

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))...)
 36
Author: Peter DeGlopper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-25 19:44:16

Osiągnąłeś granice wsparcia swojej platformy float, prawdopodobnie po 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

Zobacz sys.float_info dokładne ograniczenia, ale jest mało prawdopodobne, aby uruchomić bieżącą kombinację procesora i systemu operacyjnego, który da ci 100 znaczących cyfr w każdym przypadku; mój MacBook Pro z 64-bitowym OS X będzie obsługiwać tylko 15.

Użyj decimal Moduł wykraczający poza ograniczenia sprzętowe.

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 
 17
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-25 19:50:24

16.**256 jest zbyt duży, aby można go było przechowywać w podwójnej precyzji pływaka. Sugeruję, aby uruchomić swój cykl na mniej, jak zakres(250), ponieważ większe wartości k nie przyczyni się do pierwszych stu cyfr i tak.

Kolejną rzeczą, którą możesz spróbować, to pomnożyć przez 16.* (- k) zamiast dzielenia przez 16.*k. liczba ta zostanie zaokrąglona do zera dla dużego k, dlatego nie spowoduje błędów w uruchomieniu.

Proponuję użyć numpy.moc zamiast**, lepiej radzi sobie z przepełnieniami. Na przykład, w kod numpy.power (16., 256) ocenia się na inf, a dzielenie skończonej liczby przez inf daje zero, co pozwala uniknąć błędów w czasie pracy, tak jak metoda sugerowana w poprzednim akapicie.

 1
Author: Bence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-25 19:49:13

Używam python3. 6 AMD64, również spotykam się z tym problemem, to dlatego, że python wbudowany float jest double-precision-float, to 64 bit,w większości zadań programowania, 64 bit jest wystarczający, ale w niektórych dodatkowych zadaniach,to nie wystarczy (jak scitific computing,big data compute)

 1
Author: 员建新,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-19 07:51:23

Jest to pythonowe rozwiązanie tego problemu przy użyciu biblioteki dziesiętnej. Kod ten liczy tysiąc cyfr pi.

import decimal
def pi( prec = 10 ** 3 ):
    decimal.getcontext().prec = prec
    b =  decimal.Decimal(1)
    pi = 0
    for k in range(prec):
        pi += ( b*4/(8*k+1) - b*2/(8*k+4) - b*1/(8*k+5) - b*1/(8*k+6)) / 16**k
    return pi
print(pi())

Jest to rozwiązanie wykorzystujące tylko wbudowane liczby całkowite dowolnego rozmiaru. Działa znacznie wydajniej i pozwala policzyć dziesięć tysięcy cyfr pi.

def pi( prec = 10 ** 4 ):
    b = 10 ** prec
    pi = 0
    for k in range(prec):
        pi += ( b*4//(8*k+1) - b*2//(8*k+4) - b*1//(8*k+5) - b*1//(8*k+6)) // 16**k
    return pi
print(pi())

Uruchamiając ten kod, możesz pochwalić się swoim znajomym, że policzyłeś 10 tysięcy jako pi :).

 1
Author: Vadim Romanko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-20 15:10:51