怎么做clojure中的取幂?

时间:2011-02-20 12:32:20

标签: clojure exponentiation

如何在clojure中进行取幂? 现在我只需要整数取幂,但问题也适用于分数。

12 个答案:

答案 0 :(得分:127)

经典递归(看这个,它吹栈)

(defn exp [x n]
     (if (zero? n) 1
         (* x (exp x (dec n)))))

尾递归

(defn exp [x n]
  (loop [acc 1 n n]
    (if (zero? n) acc
        (recur (* x acc) (dec n)))))

功能

(defn exp [x n]
  (reduce * (repeat n x)))
偷偷摸摸(也吹不到堆叠,但不是那么容易)

(defn exp-s [x n]
  (let [square (fn[x] (* x x))]
    (cond (zero? n) 1
          (even? n) (square (exp-s x (/ n 2)))
          :else (* x (exp-s x (dec n))))))

文库

(require 'clojure.contrib.math)

答案 1 :(得分:74)

Clojure有一个运行良好的幂函数:我建议使用它而不是通过Java互操作,因为它正确处理所有Clojure任意精度数字类型。

对于取词而不是exptpower,它被称为pow,这可能解释了为什么它有点难以找到.....无论如何这里是一个小例子:

(use 'clojure.math.numeric-tower)  ; as of Clojure 1.3
;; (use 'clojure.contrib.math)     ; before Clojure 1.3

(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376

答案 2 :(得分:52)

您可以使用java的Math.powBigInteger.pow方法:

(Math/pow base exponent)

(.pow (bigint base) exponent)

答案 3 :(得分:11)

答案 4 :(得分:7)

user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376

答案 5 :(得分:5)

如果你真的需要一个函数而不是一个方法,你可以简单地包装它:

 (defn pow [b e] (Math/pow b e))

在此功能中,您可以将其强制转换为int或类似内容。函数通常对方法更有用,因为你可以将它们作为参数传递给另一个函数 - 在这种情况下map出现在我的脑海中。

如果你真的需要避免Java互操作,你可以编写自己的电源功能。例如,这是一个简单的函数:

 (defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
   (if (neg? p) (/ 1 result) result)))

计算整数指数的幂(即没有根)。

另外,如果您要处理大型号码,则可能需要使用BigInteger代替int

如果您正在处理非常大的数字,您可能希望将它们表示为数字列表,并编写自己的算术函数以在计算结果时输出它们并输出结果到其他一些流。

答案 6 :(得分:4)

我认为这也会奏效:

(defn expt [x pow] (apply * (repeat pow x)))

答案 7 :(得分:2)

SICP inspired完整的迭代快速版本'偷偷摸摸的'以上实施。

(defn fast-expt-iter [b n]
  (let [inner (fn [a b n]
                (cond
                  (= n 0) a
                  (even? n) (recur a (* b b) (/ n 2))
                  :else (recur (* a b) b (- n 1))))
        ]
    (inner 1 b n)))

答案 8 :(得分:2)

使用clojure.math.numeric-tower,以前为clojure.contrib.math

API Documentation

(ns user
  (:require [clojure.math.numeric-tower :as m]))

(defn- sqr
  "Uses the numeric tower expt to square a number"
  [x]
  (m/expt x 2))

答案 9 :(得分:2)

实施"偷偷摸摸"尾递归和支持负指数的方法:

(defn exp
  "exponent of x^n (int n only), with tail recursion and O(logn)"
   [x n]
   (if (< n 0)
     (/ 1 (exp x (- n)))
     (loop [acc 1
            base x
            pow n]
       (if (= pow 0)
         acc                           
         (if (even? pow)
           (recur acc (* base base) (/ pow 2))
           (recur  (* acc base) base (dec pow)))))))

答案 10 :(得分:1)

尝试

(defn pow [x n]
  (loop [x x n n r 1]
    (cond
      (= n 0) r
      (even? n) (recur (* x x) (/ n 2) r)
      :else (recur x (dec n) (* r x)))))

对于尾递归O(log n)解决方案,如果您想自己实现它(仅支持正整数)。显然,更好的解决方案是使用其他人指出的库函数。

答案 11 :(得分:0)

clojure.contrib.genric.math-functions

怎么样?

clojure.contrib.generic.math-functions库中有一个pow函数。它只是Math.pow的一个宏,更像是一种调用Java数学函数的“clojureish”方式。

http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow