繁体   English   中英

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

[英]OverflowError: (34, 'Result too large')

我收到溢出错误(溢出错误:(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())

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

您达到了平台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 ,但您不太可能遇到在任何情况下都会为您提供 100 位有效数字的当前 CPU 和操作系统组合; 我的 64 位 OS X MacBook Pro 只支持 15。

使用decimal模块超越您的硬件限制。

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 

16.**256 太大,无法存储在双精度浮点数中。 我建议你少运行你的循环,比如 range(250),因为更大的 k 值无论如何都不会影响前一百位数字。

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

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

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

这是使用十进制库解决此问题的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())

通过开始这段代码,你可以向你的朋友吹嘘你已经把一万当作圆周率了:)。

如果您需要几乎无限的精度,请使用十进制。

在极少数情况下,如果您正在执行n ** 2或类似的操作。 您可以通过将其转换为n * n来避免错误而不捕获它,因此根据您如何解决这个问题,它可能是一个可靠的解决方案。 您的数字将被称为inf而不是抛出错误, **执行幂函数并且它是抛出错误的那个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM