Scheme实现nth-root递归终止异常:1与1.0参数差异原因求助
nth-root递归终止问题与参数类型差异原因
原始问题
我写了一段Scheme代码,除nth-root外,其他过程之前测试都正常。调用(nth-root 2 9)能输出3.00...,但调用(nth-root 3 8)时递归停不下来,完全没输出,找不到问题在哪。
代码如下:
(define tolerance 0.00001) (define (fixed-point f first-guess) (define (close-enough? v1 v2) (< (abs (- v1 v2)) tolerance)) (define (try guess) (let ((next (f guess))) (if (close-enough? guess next) next (try next)))) (try first-guess)) (define (average v1 v2) (/ (+ v1 v2) 2)) (define (average-damp f) (lambda (x) (average x (f x)))) (define (compose f g) (lambda (x) (f (g x)))) (define (repeated f n) (cond ((= n 1) f) (else (compose f (repeated f (- n 1)))))) (define (log2 x) (/ (log x) (log 2))) (define (nth-root n x) (fixed-point ((repeated average-damp (floor (log2 n))) (lambda (y) (/ x (expt y (- n 1))))) 1))
更新发现
我把nth-root里的初始猜测参数1改成1.0后,程序就能正常运行了。想知道这两个参数为什么会导致这么大的差异?
原因解析
这是Scheme里整数与浮点数的类型差异导致的:
- 当传入初始值
1(整数)时,整个迭代过程会保持精确的有理数运算:expt对整数返回整数,/在整数间运算返回分数而非浮点数。以(nth-root 3 8)为例,迭代过程中猜测值会在整数/分数间跳转,而tolerance是浮点数(0.00001),有理数之间的差值始终大于该精度阈值,导致递归无法终止。 - 当传入
1.0(浮点数)时,所有后续计算会自动转为浮点运算:expt、/、average的结果都是浮点数,迭代过程中猜测值会逐步逼近真实根(2.0),每次的差值会持续缩小,直到小于tolerance,触发终止条件。
简单来说,整数初始值会让计算停留在精确的有理数范畴,无法满足浮点精度的收敛要求;而浮点数初始值会启动近似浮点运算,能正常收敛到符合精度的结果。
内容的提问来源于stack exchange,提问作者run an
相关产品推荐
相关产品推荐

