怎么做clojure中的取幂?

Pet*_*ter 98 clojure exponentiation

我怎样才能在clojure中进行取幂?现在我只需要整数取幂,但问题也适用于分数.

Joh*_*den 135

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

(defn exp [x n]
     (if (zero? n) 1
         (* x (exp x (dec n)))))
Run Code Online (Sandbox Code Playgroud)

尾递归

(defn exp [x n]
  (loop [acc 1 n n]
    (if (zero? n) acc
        (recur (* x acc) (dec n)))))
Run Code Online (Sandbox Code Playgroud)

实用

(defn exp [x n]
  (reduce * (repeat n x)))
Run Code Online (Sandbox Code Playgroud)

偷偷摸摸(也吹不到堆叠,但不是那么容易)

(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))))))
Run Code Online (Sandbox Code Playgroud)

图书馆

(require 'clojure.contrib.math)
Run Code Online (Sandbox Code Playgroud)

  • 有趣的回答! (11认同)
  • Clojure.contrib.math现已弃用,请参阅[Math.Numeric-Tower](https://github.com/clojure/math.numeric-tower) (3认同)

mik*_*era 77

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

它被称为expt而不是power或者pow可能解释为什么它有点难以找到.....无论如何这里是一个小例子:

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

(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376
Run Code Online (Sandbox Code Playgroud)

  • 我认为它现在是1.3中的"clojure.math.numeric-tower"(因为clojure.contrib被分解为单独的库) (9认同)

sep*_*p2k 56

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

(Math/pow base exponent)

(.pow (bigint base) exponent)
Run Code Online (Sandbox Code Playgroud)

  • 如果你想要准确的大整数能力,我认为你最好使用Clojure的clojure.contrib.math/expt.可能在引擎盖下做同样的事情但比通过Java互操作更好...... (3认同)
  • @Da vinci:奇怪的是,它是一种自己的语言,并且有很多Java函数(比如stringreverse) (2认同)

KIM*_*oon 7

user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376
Run Code Online (Sandbox Code Playgroud)

  • 你也可以使用文字符号:`(.pow 2M 100)` (5认同)

Dev*_*ops 6

从 Clojure 1.11 开始,clojure.math/pow标准库一起提供,并且适用于 Clojure 和 ClojureScript。


Gor*_*vic 5

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

 (defn pow [b e] (Math/pow b e))
Run Code Online (Sandbox Code Playgroud)

在此功能中,您可以将其投射到int或类似.函数通常对方法更有用,因为你可以将它们作为参数传递给另一个函数 - 在这种情况下map我想到了.

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

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

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

此外,如果您正在处理数字,您可能想要使用BigInteger而不是int.

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