2011-10-13 39 views
6

Tôi đã gặp phải NullPointerException không mong đợi trong khi triển khai một số mã SICP bắt đầu bằng Clojure. Đặc biệt, tôi muốn thực hiện thủ tục căn bậc hai lặp lại từ phần 1.1.7.SICP sqrt NullPointerException

Dưới đây là các mã:

(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))))) 

này hoạt động tốt cho các giá trị đủ nhỏ, ví dụ (sqrt 16). Tôi gặp lỗi NullPointerException clojure.lang.Numbers.lt (Numbers.java:3693) cho bất kỳ đầu vào nào lớn hơn khoảng (square 2718).

Bất kỳ ý tưởng nào?

Cập nhật với toàn traceback (trước đó là tất cả tôi nhận được trong repl):

Exception in thread "main" java.lang.NullPointerException tại clojure.lang.Numbers.lt (Numbers.java : 3693) tại sicp_in_clojure.chapter_one $ sqrt $ good_enough_QMARK ___ 14.invoke (chapter_one.clj: 40) tại sicp_in_clojure.chapter_one $ sqrt.invoke (chapter_one.clj: 43) tại sicp_in_clojure.chapter_one $ sqrt.invoke (chapter_one.clj : 37) tại sicp_in_clojure.chapter_one $ eval19.invoke (chapter_one.clj: 48) tại clojure.lang.Compiler.eval (Compiler.java:6465) tại clojure.lang.C ompiler.load (Compiler.java:6902) tại clojure.lang.Compiler.loadFile (Compiler.java:6863) tại clojure.main $ load_script.invoke (main.clj: 282) tại clojure.main $ script_opt. gọi (main.clj: 342) tại clojure.main $ main.doInvoke (main.clj: 426) tại clojure.lang.RestFn.invoke (RestFn.java:408) tại clojure.lang.Var.invoke (Var.java:401) tại clojure.lang.AFn.applyToHelper (AFn.java:161) tại clojure.lang.Var.applyTo (Var.java WEBC18) tại clojure.main.main (main.java: 37)

+0

Bạn có thể dán toàn bộ truy nguyên không? – poolie

+0

Tôi không thể tạo lại lỗi, nó hoạt động tốt cho tôi, ngay cả đối với số lượng lớn hơn. Bạn đang làm việc với phiên bản Clojure/Java nào? –

+0

Tôi cũng không thể tái sản xuất - tôi giả định các hàm vuông của bạn là (defn square [x] (* x x)). Sao chép mã bằng cách khác. – Paul

Trả lời

0

Hey nó đã làm việc tốt cho tôi. Tôi đang sử dụng clojure 1.3.0. Sau đây là đầu ra đầu cuối. Mã hoạt động tốt.

[[email protected] ~]$ 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 
+1

Bạn có thể thử mã của bạn cho (sqrt (vuông 3000))? –

+0

user => (sqrt (square 5000)) đã cho tôi 5000.000000041231 –

+0

Hấp dẫn :) Mã ở trên hoạt động hoàn hảo trên Clojure 1.2.1, nhưng tôi tiếp tục nhận NullPointerExceptions với 1.3.0. Rất kỳ quặc. –

1

Không chắc chắn nếu điều này vẫn còn có liên quan hay không, nhưng tôi nghĩ rằng nó đáng để thử nó ra bằng cách sử dụng ứng dụng LightTable Playground cho phép bạn xem cách mọi thứ được giải thích:

light table demo screenshot of above code

Các bạn đã thử với một bản dựng gần đây, cho biết bản phát hành Clojure 1.4.0 mới?

Các vấn đề liên quan