Хвостовая рекурсия в clojure
это код lisp, который использует хвостовую рекурсию.
(defun factorial (f n)
(if (= n 1)
f
(factorial (* f n) (- n 1))))
я перевожу это в код clojure, ожидая такой же оптимизации рекурсии хвоста.
(defn fact [f n]
(if (= n 1)
f
(fact (* f n) (dec n))))
однако я получил это целое переполнение (не переполнение стека) даже с небольшим числом, таким как (fact 1 30)
.
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
Я пытался с recur
, но получил ту же ошибку.
(defn factorial [f n]
(if (= n 1)
f
(recur (* f n) (dec n))))
что случилось с кодом clojure?
1 ответов
ничего, просто использовать BigInt
s:
(factorial 1N 30N) ;=> 265252859812191058636308480000000N
аргументы могут быть небольшими, но результата нет!
обратите внимание, что отмеченные версии арифметических операторов также доступны, которые поддерживают произвольную точность:
(reduce *' (range 1 31)) ;=> 265252859812191058636308480000000N