溢出错误:(34,'结果太大')

时间:2013-11-25 19:36:52

标签: python overflow decimal pi

我收到溢出错误(OverflowError:(34,'结果太大')
我想计算pi到100的小数,这是我的代码:

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 个答案:

答案 0 :(得分:25)

Python浮点数既不是仲裁精度,也不是无限大小。当k = 349时,16.**k太大了 - 几乎是2 ^ 1400。幸运的是,decimal库允许任意精度并且可以处理大小:

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

答案 1 :(得分:14)

您可能在float之后达到了平台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

请参阅sys.float_info了解具体的限制,但您不太可能遇到当前的CPU和OS组合,在任何情况下都会给您100位有效数字;我的64位OS X MacBook Pro只支持15。

使用decimal module超出您的硬件限制。

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 

答案 2 :(得分:1)

这是使用十进制库解决此问题的python解决方案。该代码计算出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())

这是仅使用内置的任意大小的整数的解决方案。它的工作效率更高,可让您计算一万位数的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())

通过启动此代码,您可以向您的朋友吹嘘您将pi算作一万:)。

答案 3 :(得分:0)

16. ** 256太大而无法存储在双精度浮点数中。我建议你运行你的周期较少,比如范围(250),因为较大的k值无论如何都不会对前100位数做出贡献。

你可能尝试的另一件事是乘以16。* ( - k)而不是除以16。 * k。对于大k,此数字将四舍五入为零,因此不会给出运行时错误。

我建议您使用numpy.power而不是**,它会更好地处理溢出。例如,在你的代码中,numpy.power(16.,256)将计算为inf,并将有限数除以inf得到零,这样可以避免运行时错误,就像上一段中建议的方法一样。

答案 4 :(得分:0)

我使用python3.6 AMD64,我也遇到了这个问题,这是因为python内置float是双精度浮点数,它是64位,在大多数编程任务中,64位就够了,但是在一些额外的任务中,这还不够(比如scitific计算,大数据计算)