0

次の末尾再帰関数を使用してオイラー問題 2を解決しようとしました。

(defun fib (num)
  (labels ((fib-helper (num a b)
         (cond ((or (zerop num)
                    (eql num 1))
                a)
               (t (fib-helper (decf num)
                              (+ a b)
                              a)))))
    (fib-helper num 1 1)))


(defun sum-even-fib (max)
  (labels ((helper (sum num)
         (cond ((oddp num) (helper sum (decf num)))
               ((zerop num) sum)
               (t (helper (+ sum (fib num))
                          (decf num))))))
    (helper 0 max)))

今、関数を使用して結果を印刷しようとすると

(defun print-fib-sum (max dir file)
  (with-open-file
      (fib-sum-str
       (make-pathname
         :name file
         :directory dir)
        :direction :output)
    (format fib-sum-str "~A~%" (sum-even-fib max))))

max値で4000000、エラーが発生します

     ("bignum overflow" "[Condition of type SYSTEM::SIMPLE-ARITHMETIC-ERROR]" nil)

から*slime-events*。番号を処理してファイルに出力する他の方法はありますか?

4

3 に答える 3

0

CL は TCO をサポートすることを約束していないため (たとえば、JVM 上の ABCL は TCO をサポートしていません - テール コールの最適化)、ループとして移植可能に記述することは理にかなっています。

(defun rev-sum-even-fib (max-val)
  (loop for a = 1 then (+ a b) and b = 0 then a
        until (> a max-val)
        when (evenp a) sum a))
于 2013-09-15T16:15:22.020 に答える