如何用C++递归实现sin(x)麦克劳林展开?条件判断遇阻
解决递归实现sin麦克劳林展开的符号判断问题
首先得指出你代码框架里的一个小疏漏:你当前写的pow(x,n-2)/fact(n-2)搞反了项的次数。比如当n=3时,我们需要在sin(1,x)的基础上减去x³/3!,而不是x¹/1!,所以这里应该改成pow(x,n)/fact(n)才行,否则计算结果会完全错误。
接下来解决你最困惑的符号交替问题,先梳理麦克劳林展开的符号规律:
- 第1项(次数1):正号
- 第2项(次数3):负号
- 第3项(次数5):正号
- 第4项(次数7):负号
- ...以此类推
观察次数n(都是奇数)的规律:
- 当n除以4余1时(比如1、5、9...),对应正号项
- 当n除以4余3时(比如3、7、11...),对应负号项
基于这个规律,我们可以直接用n % 4 == 3作为if的判断条件,完美实现交替加减。
修正后的完整代码如下:
// 假设fact函数已经实现,用于计算阶乘 double fact(int num) { double result = 1; for(int i=1; i<=num; i++){ result *= i; } return result; } double sin(int n, double x){ // 参数合法性校验:n必须是正奇数,否则返回错误值(这里以返回0为例) if(n < 1 || n % 2 == 0){ return 0; } if(n == 1) return x; // 第一项:x^1/1! if(n % 4 == 3) // 当前项是负号,从递归结果中减去该项 return sin(n-2, x) - (pow(x, n)/fact(n)); else // 当前项是正号,在递归结果中加上该项 return sin(n-2, x) + (pow(x, n)/fact(n)); }
为什么这个条件可行?
麦克劳林展开的通项公式是:(-1)^k * x^(2k+1)/(2k+1)!,其中k从0开始计数。对于我们传入的次数n=2k+1,可得k=(n-1)/2:
- 当k为偶数时(对应n=1、5、9...),
(-1)^k=1,正号,此时n%4=1 - 当k为奇数时(对应n=3、7、11...),
(-1)^k=-1,负号,此时n%4=3
所以用n%4==3判断负号项完全契合通项的符号规律。
另外补充个小建议:递归时一定要做参数校验,确保n是正奇数,否则会出现无限递归(比如传入偶数n,会一直减2直到负数,永远触发不了n==1的终止条件)。
内容的提问来源于stack exchange,提问作者morty
相关产品推荐
相关产品推荐

