为什么尾递归Collat​​z猜想导致堆栈溢出?

时间:2012-03-16 08:13:15

标签: lisp scheme stack-overflow guile collatz

我在Scheme中写过Collat​​z猜想:

(define C
  (lambda (n)
    (cond
     ((eq? n 1) 1)
     ((even? n) (C (/ n 2)))
     (else (C (+ (* n 3) 1))))))

这是一个尾递归调用,但是当我调用(C 121)时,我得到堆栈溢出:

guile> (trace C)
(C)
guile> (C 121)
[C 121]
[C 364]
[C 182]
[C 91]
[C 274]
[C 137]
[C 412]
[C 206]
[C 103]
[C 310]
[C 155]
[C 466]
[C 233]
[C 700]
[C 350]
[C 175]
[C 526]
[C 263]
[C 790]
[C 395]
[C 1186]
ERROR: Stack overflow
ABORT: (stack-overflow)

为什么正确的尾递归会导致溢出?如您所见,我使用Guile作为Scheme解释器(版本1.8.7)。

2 个答案:

答案 0 :(得分:2)

定义的程序在Racket中运行良好。这对我来说似乎是一个错误,或者是对你的环境非常具体的东西。

几乎肯定与您的问题无关,但有点挑剔:使用比较(= n 1)代替(eq? n 1)

答案 1 :(得分:0)

(define C
  (lambda (n)
    (cond
     ((eq? n 1) 1)
     ((even? n) (C (/ n 2)))
     (else (C (+ (* n 3) 1))))))

这看起来总是返回1(或无限循环 - 猜想仍然未经证实)。在递归调用周围是否存在隐藏(+1 ...)的转录错误?