clojure - 递归调用导致溢出

标签 clojure

我正在尝试解决项目欧拉第二个问题。为什么下面的代码会导致堆栈溢出?我正在使用 recur,因此它不应该将所有递归调用存储在堆栈上。

(defn sum
  [[a b]]
  [b (+ a b)])

(defn fib-r
  ([n] (fib-r n 0 [0 1]))
  ([n s [a b]]
     (if (= n 0)
       s
       (let [[c d] (sum [a b])
             e (if (even? c) c 0)
             f (+ s e)]
         (recur (dec n) f [c d])))))

(fib-r 4000000)

最佳答案

您遇到整数溢出(而不是堆栈溢出) 如果您使用 BigInts(BigInt 文字以 N 结尾),那么 Clojure 将 愉快地计算出正确的结果:

(defn fib-r                                                                                          
  ([n] (fib-r n 0N [0N 1N]))                                                                     
  ([n s [a b]]                                                                                     
     (if (= n 0N)                                                                            
       s                                                                            
       (let [[c d] (sum [a b])                                               
             e (if (even? c) c 0N)                               
             f (+ s e)]                             
         (recur (dec n) f [c d])))))
#'autotestbed.core/fib-r                                                                                               
autotestbed.core> (fib-r 40000)
1158997879999727672946417013062336891791160667328280503727448.... big number

关于clojure - 递归调用导致溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11130540/

相关文章:

clojure - 如何获取Clojure:pre和:post报告其失败值?

clojure - 在 clojure 中是否有任何好的库或策略来测试多线程应用程序?

loops - 循环遍历宏的参数

clojure - 在宏上调用宏

Clojure rseq 恒定时间?

clojure - 在 Clojure 中获取函数的参数类型提示

clojure - clojure 中的笛卡尔积

clojure - 如何获取 clojure 数组映射来维护 assoc 之后的插入顺序?

clojure - 在 Clojure 中创建 Uberjar 的问题

clojure - 有没有一种方法可以像 Clojure 中那样在 Common Lisp 中使用关键字作为函数?