【问题标题】:Why this code does not throw StackOverflow exception为什么这段代码不会抛出 StackOverflow 异常
【发布时间】:2014-11-16 06:10:10
【问题描述】:

在 clojure v1.6.0 中,此代码永远运行并消耗 100% 的一个内核:

(defn average [x y] (/ (+ x y) 2))

(defn improve [guess x]
  (average guess (/ x guess)))

(defn sqrt-iter [guess x]
  (sqrt-iter (improve guess x) x))

(sqrt-iter 1 4)

我希望它会立即抛出 StackOverflowError,但事实并非如此。

任何解释为什么会发生?

【问题讨论】:

    标签: clojure jvm


    【解决方案1】:

    因为 1 很长。代码开始计算极长的有理数,并在几次迭代后减速到爬行。如果您使用 1.0 和 4 运行它,它会在数千次调用后非常快地破坏堆栈(可能会因您的 jvm 参数而异)。

    【讨论】:

    • 要溢出它只需要执行数千次调用。真的很长的算术那么慢以至于它不能快速计算 10k 的除法和求和吗?
    • 算术不算长。它是一个比率,它在分母和分子中包含 BigIntegers。 BigIntegers 将任意增长。见github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多