【问题标题】:SICP sqrt NullPointerExceptionSICP sqrt NullPointerException
【发布时间】:2011-10-13 04:11:26
【问题描述】:

我在 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)

【问题讨论】:

  • 你能粘贴整个回溯吗?
  • 我无法重现该错误,它对我来说很好,即使对于更大的数字也是如此。您正在使用哪些版本的 Clojure / Java?
  • 我也无法重现——我假设你的平方函数是 (defn square [x] (* x x))。否则复制粘贴代码。
  • 保罗:是的,我忘记发布我的正方形定义了;我将在其中进行编辑。
  • 我正在使用 Clojure 1.3.0。 java 版本 "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03-384-10M3425) Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-384, mixed mode)

标签: clojure nullpointerexception sicp


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • user=> (sqrt (square 5000)) 给了我 5000.000000041231
    • 迷人 :) 上面的代码在 Clojure 1.2.1 上完美运行,但我在 1.3.0 中不断收到这些 NullPointerExceptions。很奇怪。
    • 我的 clojure 版本是 1.3.0 。你可以在我的回复中看到它!我认为这将是由于您的 clojure 安装中的问题。确保您没有使用测试版(以防测试版中存在任何错误)
    • 顺便说一下,这是我的java安装,java版本“1.6.0_22” OpenJDK Runtime Environment (IcedTea6 1.10.3) (ArchLinux-6.b22_1.10.3-1-x86_64) OpenJDK 64- Bit Server VM(build 19.0-b09,混合模式)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 2011-11-05
    • 2017-02-03
    • 2010-12-26
    • 2012-12-15
    • 2021-05-23
    相关资源
    最近更新 更多