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

Haskell实现e^x泰勒递归函数结果不符问题求助

问题分析:整数溢出导致计算错误

你的代码逻辑本身是对的——泰勒级数展开计算e^x确实是累加从k=0到n的x^k/k!,但问题出在大整数溢出上。

Haskell中的Int类型是固定精度的整数(通常是32位或64位),当你计算x^n时,比如10^20,这个值是100000000000000000000,远超过64位Int的最大值(约9e18)。此时整数会溢出,变成一个错误的负数或乱码值,再转成Float后,整个项的计算就完全偏离了正确值,最终导致总和不符合预期。

另外,你的代码每次递归都重新计算factorial n,这会让时间复杂度变成O(n²),效率很低,但这不是结果错误的直接原因。

解决方案:避免大整数溢出

有两种简单的修复方式,推荐第一种(更高效且精度更好):

方法1:递推计算每一项(推荐)

不要每次单独计算x^n和n!,而是利用前一项的结果递推当前项:term_k = term_{k-1} * x / k。这样全程用浮点数计算,完全避开大整数问题,同时时间复杂度降到O(n)。

修改后的代码:

consigna3 :: Int -> Int -> Float
consigna3 x n = go n 1.0 0.0
  where
    -- go 当前项的k值 当前项的值 累加和
    go 0 term sum = sum + term  -- 加上k=0的项(x^0/0! = 1)
    go k term sum = let nextTerm = term * fromIntegral x / fromIntegral k
                    in go (k-1) nextTerm (sum + term)

方法2:使用任意精度整数

改用Integer类型(Haskell的任意精度整数)来计算x^n和阶乘,避免溢出,之后再转成Float:

factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n-1)

consigna3 :: Int -> Int -> Float
consigna3 _ 0 = 1.0
consigna3 x n = let xInt = toInteger x
                    nInt = toInteger n
                in (fromIntegral(xInt ^ nInt) / fromIntegral(factorial nInt)) + consigna3 x (n-1)
验证结果

用第一种方法测试你的示例:

  • consigna3 10 20 会返回21991.48左右
  • consigna3 10 30 会返回22026.46左右
    其他示例也会符合预期。

内容的提问来源于stack exchange,提问作者Ignacio Mauricio Rios

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:42:55