在DrRacket(Scheme)中实现欧拉数遇问题:自定义阶乘与e函数结果异常
在DrRacket中简单实现欧拉数e的正确方法
我完全懂你的困扰——想在DrRacket里实现欧拉数e,自己写了阶乘和e的函数却结果不对,搜来的方案又太复杂。咱们从最基础的正确实现入手,一步步理清问题。
首先,阶乘函数是计算e的核心,先确保它的定义符合数学规则:
; 正确的递归阶乘函数 (define (factorial n) (if (= n 0) 1 ; 数学上0! = 1,这是关键的终止条件 (* n (factorial (- n 1)))))
很多人在这里容易犯的错误是把0的阶乘返回0,这会直接导致后续e的计算完全错误,一定要注意这个细节。
接下来是e的计算,欧拉数e的级数展开式是:
e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! + ...
我们可以写一个直观的递归版本来计算前n项的近似值,注意要使用浮点数除法,否则整数除法会让大部分项变成0,结果完全不对:
; 递归版e近似值计算,计算到第n项(从0开始计数) (define (e-approx n) (if (= n 0) 1.0 ; 转成浮点数,确保后续除法是小数运算 (+ (/ 1.0 (factorial n)) (e-approx (- n 1)))))
比如调用(e-approx 10),你会得到大约2.7182818011463845,已经很接近真实的e值了。
如果担心递归深度太大导致栈溢出,我们可以写一个更高效的迭代版本,这个版本不会重复计算阶乘,性能更好:
; 迭代版e近似值计算,效率更高 (define (e-approx-iter n) ; 内部迭代函数:count当前项数,sum当前累加和,fact当前项的阶乘 (define (iter count sum fact) (if (> count n) sum (iter (+ count 1) (+ sum (/ 1.0 fact)) (* fact (+ count 1))))) ; 直接更新阶乘,不用重复计算 (iter 0 0.0 1)) ; 初始状态:第0项,和为0,阶乘是0! = 1
调用(e-approx-iter 20)会得到2.7182818284590455,这个值已经非常接近真实的e(约2.718281828459045)了。
最后总结几个常见的错误原因:
- 阶乘的终止条件错误:把0!返回0而不是1,直接毁掉整个计算基础
- 没有使用浮点数除法:用整数除法的话,除了前两项,后面的1/n!都会变成0,结果只能得到1或2
- 项数不足:如果只计算前3、4项,结果会和e有明显差距,但这是近似程度的问题,不是代码错误
内容的提问来源于stack exchange,提问作者user9163844
相关产品推荐
相关产品推荐

