SICP sqrt NullPointerException - PullRequest
       27

SICP sqrt NullPointerException

6 голосов
/ 13 октября 2011

Я столкнулся с неожиданным исключением 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)

Ответы [ 2 ]

1 голос
/ 27 июня 2012

Не уверен, что это все еще актуально или нет, но я подумал, что стоит попробовать это с помощью приложения LightTable Playground , которое позволяет увидеть, как все интерпретируется:

light table demo screenshot of above code

Пробовали ли вы с недавней сборкой, скажем, новую Clojure 1.4.0 релиз?

0 голосов
/ 13 октября 2011

Эй, у меня все работало нормально.Я использую clojure 1.3.0.Ниже вывод терминала. Код работает нормально.

[user@myhost ~]$ clj 
Clojure 1.3.0
user=> (defn square [x] (* x x))
#'user/square
(defn abs [x]
  (cond 
    (< x 0) (- x)
    :else x))
#'user/abs
(defn average [x y]
  (/ (+ x y) 2))
#'user/average
(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)))))
#'user/sqrt
user=> (sqrt 16)
4.000000636692939
user=> (sqrt 2718)
52.134441897781194
user=> (sqrt 3000)
54.77225658092904
...