平方根近似Clojure

时间:2018-03-18 19:24:34

标签: clojure rounding approximation square-root

我收到错误但不知道如何修复它。我必须用近似计算平方根,它应该停在第20个元素上。

  • 无法在此上下文中解析符号:aprox,编译:(/ home / jdoodle.clj:2:2)

代码:

(defn msqrt [n]
    (aprox  (n 1.0 1)))
(defn aprox [n prox part]
(if (= part 20)
    prox
(+ (/ n (* 2 (aprox n part (+ part 1)))) (/ (aprox n prox (+ part 1))2)))
)
(msqrt 9)

2 个答案:

答案 0 :(得分:1)

在Clojure中,您声明函数的顺序。他们不会像Javascript一样被提升。您可以通过以下方式解决此问题:

  1. 将您的defn aprox移到defn msqrt
  2. 之上
  3. declare aprox添加到文件顶部以使其可用
  4. https://clojuredocs.org/clojure.core/declare

答案 1 :(得分:0)

corrected答案会编译,但是,但不会做它应该做的事情。 part函数中对aprox的第一次引用应该是prox

(defn aprox [n prox part]
  (if (= part 20)
      prox
      (+
        (/ n (* 2 (aprox n prox (inc part))))
        (/ (aprox n prox (inc part)) 2))))

我抓住机会改善布局和简洁。

有效:

> (msqrt 9)
=> 3.0

但它会进行两次相同的递归调用。它只需要这样做一次:

(defn aprox [n prox part]
  (if (= part 20)
      prox
      (let [deeper-prox (aprox n prox (inc part))]
        (+
          (/ n (* 2 deeper-prox))
          (/ deeper-prox 2)))))

现在大约有20个递归调用,而不是大约一百万个(2 ^ 20)。

我们可以看到它是如何工作的。在递归调用中,

  • part参数计数到20,创建一个二十个调用堆栈 深;
  • prox参数使用递归来生成和 返回自己的改进估计;
  • n参数未经更改地传递。

我们可以通过重复改进过程二十次并将其折叠到msqrt函数中来获得相同的效果:

(defn msqrt [n]
  (loop [prox 1.0, part 20]
    (if (pos? part)
      (recur (+ (/ n (* 2 prox)) (/ prox 2)) (dec part))
      prox)))