Я столкнулся с неожиданным исключением NullPointerException при реализации начального кода SICP в Clojure. В частности, я хочу реализовать итерационную процедуру получения квадратного корня из раздела 1.1.7.
Вот код:
(defn square [x] (* x x))
(defn abs [x]
(cond
(< x 0) (- x)
:else x))
(defn average [x y]
(/ (+ x y) 2))
(defn sqrt
([x] (sqrt 1.0 x))
([guess x]
(letfn [(good-enough? [guess]
(< (abs (- (square guess) x)) 0.001))
(improve [guess]
(average guess (/ x guess)))]
(if (good-enough? guess)
guess
(recur (improve guess) x)))))
Это прекрасно работает при достаточно малых значениях, например (sqrt 16)
. Я получаю ошибку NullPointerException clojure.lang.Numbers.lt (Numbers.java:3693)
для любых входов больше, чем приблизительно (square 2718)
.
Есть идеи?
Обновление со всей трассировкой (предыдущая - это все, что я получаю в ответе):
Исключение в потоке "main" java.lang.NullPointerException
на clojure.lang.Numbers.lt (Numbers.java:3693)
в sicp_in_clojure.chapter_one $ sqrt $ good_enough_QMARK ___ 14.invoke (chapter_one.clj: 40)
в sicp_in_clojure.chapter_one $ sqrt.invoke (chapter_one.clj: 43)
в sicp_in_clojure.chapter_one $ sqrt.invoke (chapter_one.clj: 37)
в sicp_in_clojure.chapter_one $ eval19.invoke (chapter_one.clj: 48)
at clojure.lang.Compiler.eval (Compiler.java:6465)
at clojure.lang.Compiler.load (Compiler.java:6902)
at clojure.lang.Compiler.loadFile (Compiler.java:6863)
в clojure.main $ load_script.invoke (main.clj: 282)
в clojure.main $ script_opt.invoke (main.clj: 342)
в clojure.main $ main.doInvoke (main.clj: 426)
at clojure.lang.RestFn.invoke (RestFn.java:408)
at clojure.lang.Var.invoke (Var.java:401)
at clojure.lang.AFn.applyToHelper (AFn.java:161)
at clojure.lang.Var.applyTo (Var.java:518)
at clojure.main.main (main.java:37)