How can I do exponentiation in clojure? For now I\'m only needing integer exponentiation, but the question goes for fractions too.
Try
(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)))))
for a tail-recursive O(log n) solution, if you want to implement it yourself (only supports positive integers). Obviously, the better solution is to use the library functions that others have pointed out.
You can use java's Math.pow
or BigInteger.pow
methods:
(Math/pow base exponent)
(.pow (bigint base) exponent)
Implementation of "sneaky" method with tail recursion and supporting negative exponent:
(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)))))))
Clojure has a power function that works well: I'd recommend using this rather than going via Java interop since it handles all the Clojure arbitrary-precision number types correctly. It is in namespace clojure.math.numeric-tower.
It's called expt
for exponentiation rather than power
or pow
which maybe explains why it's a bit hard to find ... anyway here's a small example (note that use
works but better use require):
(require '[clojure.math.numeric-tower :as math :refer [expt]]) ; as of Clojure 1.3
;; (use 'clojure.contrib.math) ; before Clojure 1.3
(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376
You must first install the Java package org.clojure.math.numeric-tower
to make the Clojure namespace clojure.math.numeric-tower
accessible!
On the command line:
$ lein new my-example-project
$ cd lein new my-example-project
Then edit project.clj
and add [org.clojure/math.numeric-tower "0.0.4"]
to the dependencies vector.
Start a lein REPL (not a clojure REPL)
$ lein repl
Now:
(require '[clojure.math.numeric-tower :as math])
(math/expt 4 2)
;=> 16
or
(require '[clojure.math.numeric-tower :as math :refer [expt]])
(expt 4 2)
;=> 16
How about clojure.contrib.genric.math-functions
There is a pow function in the clojure.contrib.generic.math-functions library. It is just a macro to Math.pow and is more of a "clojureish" way of calling the Java math function.
http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow
When this question was originally asked, clojure.contrib.math/expt was the official library function to do this. Since then, it has moved to clojure.math.numeric-tower