为什么我在进行浮点指数运算时会出现“OverflowError:(34,‘结果太大’)”或“OverflowError:(34,‘数值结果超出范围’)”?

2025-02-18 09:23:00
admin
原创
150
摘要:问题描述:我尝试使用此代码将圆周率计算到小数点后几位: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....

问题描述:

我尝试使用此代码将圆周率计算到小数点后几位:

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

为什么我会收到这样的错误OverflowError: (34, 'Result too large')


解决方案 1:

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

解决方案 2:

您已达到平台支持的限制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 位有效数字;我的 MacBook Pro 搭载 64 位 OS X,仅支持 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 

解决方案 3:

16.**256 太大,无法存储在双精度浮点数中。我建议您运行较小的循环,例如 range(250),因为无论如何,较大的 k 值不会对前 100 位数字产生影响。

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

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

解决方案 4:

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

解决方案 5:

这是使用十进制库对此问题的 Python 解决方案。此代码计算圆周率的一千位数字。

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

这是一个仅使用内置任意大小整数的解决方案。它工作效率更高,并允许您计算圆周率的一万位数字。

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

通过启动此代码,您可以向朋友吹嘘您已经将一万数成了圆周率:)。

解决方案 6:

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

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

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3949  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2735  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   74  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   82  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   68  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用