SICP sqrt 空指针异常

发布于 2024-12-09 17:25:56 字数 1702 浏览 0 评论 0 原文

我在 Clojure 中实现一些开始的 SICP 代码时遇到了意外的 NullPointerException。特别是,我想实现 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)。对于任何大于大约 (square 2718) 的输入,我都会收到 NullPointerException clojure.lang.Numbers.lt (Numbers.java:3693) 错误。

有什么想法吗?

更新整个回溯(前一个是我在 repl 中得到的全部):

线程“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) 在 clojure.lang.Compiler.eval(Compiler.java:6465) 在 clojure.lang.Compiler.load(Compiler.java:6902) 在 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) 在 clojure.lang.RestFn.invoke(RestFn.java:408) 在 clojure.lang.Var.invoke(Var.java:401) 在 clojure.lang.AFn.applyToHelper(AFn.java:161) 在 clojure.lang.Var.applyTo(Var.java:518) 在 clojure.main.main(main.java:37)

I've encountered an unexpected NullPointerException while implementing some beginning SICP code in Clojure. In particular, I want to implement the iterative square root procedure from section 1.1.7.

Here's the code:

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

This works fine for small enough values, e.g. (sqrt 16). I get a NullPointerException clojure.lang.Numbers.lt (Numbers.java:3693) error for any inputs larger than approximately (square 2718).

Any ideas?

Update with the whole traceback (the previous one is all I get in the repl):

Exception in thread "main" java.lang.NullPointerException
at clojure.lang.Numbers.lt(Numbers.java:3693)
at sicp_in_clojure.chapter_one$sqrt$good_enough_QMARK___14.invoke(chapter_one.clj:40)
at sicp_in_clojure.chapter_one$sqrt.invoke(chapter_one.clj:43)
at sicp_in_clojure.chapter_one$sqrt.invoke(chapter_one.clj:37)
at 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)
at clojure.main$load_script.invoke(main.clj:282)
at clojure.main$script_opt.invoke(main.clj:342)
at 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

知你几分 2024-12-16 17:25:56

不确定这是否仍然相关,但我认为值得使用 LightTable Playground 应用程序,可让您查看事物的解释方式:

您是否尝试过最近的版本,例如新的 Clojure 1.4.0 版本?

Not sure if this is still relevant or not, but I thought it worth trying it out using the LightTable Playground app that lets you see how things are interpreted:

light table demo screenshot of above code

Have you tried with a recent build, say the new Clojure 1.4.0 release?

心的憧憬 2024-12-16 17:25:56

嘿,这对我来说效果很好。我正在使用 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

Hey it worked fine for me. I Am using clojure 1.3.0. Following is the terminal output.The code works fine.

[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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文