I’am getting an overflow error(OverflowError: (34, ‘Result too large’)
I want to calculate pi to 100 decimals here’s my 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())
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Python floats are neither arbitary precision nor of unlimited size. When k = 349, 16.**k is much too large – that’s almost 2^1400. Fortunately, the decimal library allows arbitrary precision and can handle the size:
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))...)
Method 2
You reached the limits of your platform’s float support, probably after 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
See sys.float_info for the exact limitations, but you are unlikely to run into a current CPU and OS combination that’ll give you 100 significant digits in any case; my MacBook Pro with 64-bit OS X will only support 15.
Use the decimal module to go beyond your hardware limitations.
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
Method 3
16.**256 is too large to be stored in double precision float. I suggest that you run your cycle for less, like range(250), because larger k values will not contribute to the first hundred digits anyway.
Another thing you might try is to multiply by 16.*(-k) instead of dividing by 16.*k. This number will be rounded to zero for large k, therefore will not give you runtime errors.
I suggest that you use numpy.power instead of **, it handles overflows better. For example, in your code numpy.power(16.,256) would evaluate to inf, and dividing a finite number by inf gives zero, which avoids runtime errors just like the method suggested in the previous paragraph.
Method 4
I use python3.6 AMD64,I also meet this problem,this is because python built-in float is double-precision-float,it’s 64 bit,in most progamming task,64 bit is enough,but in some extra task,it’s not enough(like scitific computing,big data compute)
Method 5
This is a python solution to this problem using the decimal library. This code counts one thousand digits of 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())
This is a solution using only the built-in any size integers. It works much more efficiently and allows you to count ten thousand digits of 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())
By starting this code, you can brag to your friends that you have counted ten thousand as pi :).
Method 6
Use decimal if you need nearly infinite precision.
In some rare cases if you’re doing n ** 2 or something like that. You can avoid the error without catching it by just converting that to n * n so depending on how you get to your this problem it might be a solid fix for this. Your numbers will be called inf rather than throwing an error, the ** does the power function and it is the one throwing the error.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0