You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:40:23