递归实现Horner法计算泰勒级数:两段代码结果为何差异显著?
递归实现泰勒级数的差异与精度问题分析
第一段代码(正确实现)
这段代码通过静态累加变量结合Horner法计算泰勒级数,能得到符合预期精度的结果:
#include <stdio.h> double t(int n,int m){ static double a = 1.0; if(m==0) return a; a = 1+(double)n/m*a; return t(n,m-1); } int main(){ printf("%lf\n",t(4,1500)); }
第二段代码(结果不符合预期)
这段代码尝试用单返回语句实现递归,但输出结果为1.002674,与预期不符:
#include <stdio.h> double e(int x, int m){ if(m==0) return 1.0; return 1+((double)x/m)*e(x,m-1); } int main(){ printf("%lf\n",e(4,1500)); }
两段代码的核心差异
计算顺序与Horner法的应用
- 第一段代码是从高次项往低次项迭代计算,严格遵循Horner法的改写逻辑:
泰勒级数 (e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + ... + \frac{x^m}{m!}) 用Horner法可改写为:
(e^x = (...((1 + \frac{x}{m}) * 1 + \frac{x}{m-1}) * 1 + ...) + \frac{x}{1}) + 1)
静态变量a每次迭代更新当前累加值,从m=1500逐步计算到m=0,最终得到正确结果。 - 第二段代码是从低次项往高次项递归计算,递归展开后实际计算的表达式为:
(e(x,m) = 1 + \frac{x}{m}(1 + \frac{x}{m-1}(1 + ...*(1 + \frac{x}{1}*1)...)))
这完全偏离了泰勒级数的Horner改写形式,本质上计算的不是目标的 (e^x)。
- 第一段代码是从高次项往低次项迭代计算,严格遵循Horner法的改写逻辑:
变量存储与逻辑本质
- 第一段代码的递归只是用来控制循环次数,核心是通过静态变量
a迭代更新中间结果,属于迭代式递归。 - 第二段代码是纯递归,每次调用都重新计算子问题,没有保存中间结果,且计算顺序错误导致表达式完全偏离需求。
- 第一段代码的递归只是用来控制循环次数,核心是通过静态变量
结果不符的根本原因
第二段代码的错误并非单纯精度损失,而是计算的表达式本身就不是目标泰勒级数。当m=1500时,(\frac{x}{m})的值极小(4/1500≈0.002666),递归展开后每一层都是乘以一个接近0的数再加1,最终结果会趋近于1,这就是输出为1.002674的原因。而第一段代码的计算顺序符合Horner法的优化,能正确累加泰勒级数的各项,得到接近 (e^4≈54.59815) 的正确结果。
内容的提问来源于stack exchange,提问作者Amitava Bose
相关产品推荐
相关产品推荐

