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())
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))...)
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
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.
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)
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 :).
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