C#递归正弦函数两种实现差异:为何一种返回错误结果?
咱们直接点出核心问题:虽然两个函数打印的中间项完全一致,但递归返回值的处理逻辑有着本质区别,这就是为什么一个结果正确、一个完全跑偏的原因。
一、两种实现的核心技术差异
错误实现(sinus):嵌套式的递归返回加减
这个函数的递归逻辑是把当前项直接和子递归的返回值做加减后返回:
if (mustAdd) return result += sinus(number, exp + 2, !mustAdd); else return result -= sinus(number, exp + 2, !mustAdd);
简单说,它的计算过程是嵌套的:每一层递归的结果都会被外层递归用相反的符号再做一次加减。比如初始调用sinus(π)时,mustAdd是false,逻辑变成当前项 - 下一层递归的结果;而下一层递归的结果又是当前项 + 再下一层递归的结果,以此类推,整个计算链完全偏离了泰勒级数的线性交替加减逻辑。
正确实现(Altersinus):累加器式的线性累积
这个函数用了一个result参数作为累加器,每次递归先把当前项按符号加到累加器里,再把更新后的累加器传给下一层递归,最后返回最终累积的结果:
if (mustAdd) result += tmp; else result -= tmp; result = Altersinus(number, exp + 2, !mustAdd, precision, result);
这是标准的线性累积逻辑:每一步都把当前项的贡献正确叠加到总结果中,完全符合泰勒级数sin(x) = x - x³/3! + x⁵/5! - x⁷/7! + ...的交替加减规则。
二、为什么错误实现会返回离谱结果?
咱们拿你提供的测试用例拆解错误逻辑:
给定的项依次是(对应符号:加、减、加、减...):3.14159...、5.16771...、2.55016...、0.59926...、0.08214...、0.00737...、0.000466...、2.1915e-5、7.952e-7
错误实现的嵌套计算过程是这样的:
返回值 = 3.14159 - (5.16771 + (2.55016 - (0.59926 + (0.08214 - (0.00737 + (0.000466 - (2.1915e-5 + 7.952e-7)))))))
一步步计算后最终得到的就是你看到的-3.90268777359824——这个结果完全不符合泰勒级数定义,因为嵌套的加减把符号逻辑彻底打乱了。
而正确实现的线性累积过程是:
总结果 = 0 + 3.14159 - 5.16771 + 2.55016 - 0.59926 + 0.08214 - 0.00737 + 0.000466 - 2.1915e-5 + 7.952e-7
计算后结果趋近于sin(π)=0,也就是你看到的-7.72785889430639E-07,这才是符合预期的结果。
总结
错误实现的问题在于递归返回时的嵌套加减逻辑,它没有正确遵循泰勒级数的线性交替加减规则,而是把后续所有项的结果用嵌套方式反复反转符号,导致最终结果完全错误。而正确实现通过累加器参数逐步累积每一项的贡献,完美匹配了级数的计算逻辑,所以得到了正确结果。
内容的提问来源于stack exchange,提问作者user2246699

