You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算大区间斐波那契数列和时出现溢出错误该如何解决

斐波那契数列区间和大数计算溢出问题解决方案

问题复现

你最初使用通项公式实现斐波那契区间和计算时遇到两轮溢出问题:

  1. 原生math库版本
    仅支持r≤1472的场景,超过即抛出OverflowError: (34, 'Result too large'),原始代码如下:
import math
def fib(n):
    s5 = math.sqrt(5)
    phi = (1 + s5) / 2
    return int(round(pow(phi, n) / s5))

def calculateSum(l, r):
    sum = fib(r + 2) - fib(l + 1)
    res = sum % 1000000007
    return res

l = 5
r =1400
print(calculateSum(l,r))
  1. decimal优化版本
    调整后仅支持r≤4550000的场景,超过仍抛出decimal.Overflow错误,优化后代码如下:
import decimal
def fib(n):
    s5 = decimal.Decimal(5).sqrt()
    phi = (1 + s5) / 2
    return int(round(pow(phi, n) / s5))

def calculateSum(l, r):
    sum = fib(r + 2) - fib(l + 1)
    res = sum % 1000000007
    return res

l = 5
r =4500000
print(calculateSum(l,r))

核心问题根源

通项公式法依赖浮点数/高精度十进制数的幂运算,斐波那契数值随n指数级增长,会快速突破数据类型的存储上限;且你需要的是对1e9+7取模后的结果,先计算完整大数再取模的方式完全没有必要,既浪费算力又容易触发溢出。

最优解决方案

直接使用矩阵快速幂+模运算实现,不需要计算完整的斐波那契大数,全程整数运算无溢出风险,时间复杂度仅为O(logn),支持n到1e18级别的计算需求:

MOD = 10**9 + 7

def matrix_mult(a, b):
    # 2*2矩阵乘法,全程带模运算避免溢出
    return [
        [(a[0][0]*b[0][0] + a[0][1]*b[1][0]) % MOD,
         (a[0][0]*b[0][1] + a[0][1]*b[1][1]) % MOD],
        [(a[1][0]*b[0][0] + a[1][1]*b[1][0]) % MOD,
         (a[1][0]*b[0][1] + a[1][1]*b[1][1]) % MOD]
    ]

def matrix_pow(mat, power):
    # 矩阵快速幂,对数级降低运算次数
    result = [[1, 0], [0, 1]] # 初始化单位矩阵
    while power > 0:
        if power % 2 == 1:
            result = matrix_mult(result, mat)
        mat = matrix_mult(mat, mat)
        power = power // 2
    return result

def fib_mod(n):
    if n == 0:
        return 0
    mat = [[1, 1], [1, 0]]
    res_mat = matrix_pow(mat, n-1)
    return res_mat[0][0] % MOD

def calculateSum(l, r):
    # 斐波那契区间和公式:sum(l~r) = fib(r+2) - fib(l+1)
    return (fib_mod(r+2) - fib_mod(l+1)) % MOD

# 测试用例,支持任意大的r值
l = 5
r = 10**18
print(calculateSum(l, r))

方案优势

  • 全程整数运算,无浮点数精度损失,也不会触发任何溢出错误
  • 运算效率极高,即使r为1e18,也仅需要60次左右的矩阵运算,毫秒级即可出结果
  • 没有数值上限限制,完全适配任意大的计算需求

替代方案(不推荐)

如果坚持要使用通项公式法,可以手动调高decimal的精度和溢出阈值,但效率会随r增大快速下降:

import decimal
ctx = decimal.getcontext()
ctx.prec = 2000000 # 根据r的大小调整,r每增加1,prec需要至少加1
ctx.Emax = 999999999 # 调高超额上限避免溢出

内容的提问来源于stack exchange,提问作者DRV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 14:27:03