Exponentiation (expt / pow)

225 views
Skip to first unread message

Mark Engelberg

unread,
Dec 31, 2008, 7:19:40 PM12/31/08
to clo...@googlegroups.com
As I posted a couple weeks ago, I've been finding it awkward that
Clojure doesn't have too many math functions that know how to "do the
right thing" with the various numeric types it uses. The one that's
been bothering me the most is the lack of an expt function. Calling
Math/pow automatically coerces everything to doubles, which isn't
necessarily the desired behavior.

So I took this as an opportunity to learn how Clojure's multimethods
work, and coded up a sample expt implementation, which I've attached
and pasted below. I'd like to hear some comments on whether I'm
utilizing multimethods correctly, and whether functions like this
would be beneficial for inclusion in the clojure contribs. If people
find this useful, there are a few other math functions which would
benefit from this sort of conversion as well.

(derive java.lang.Integer ::exact)
(derive java.lang.Integer ::integer)
(derive java.math.BigInteger ::exact)
(derive java.math.BigInteger ::integer)
(derive java.lang.Long ::exact)
(derive java.lang.Long ::integer)
(derive java.math.BigDecimal ::exact)
(derive clojure.lang.Ratio ::exact)
(derive java.lang.Double ::inexact)

(defmulti expt (fn [x y] [(class x) (class y)]))

(defn- expt-int [base pow]
(loop [n pow, y 1, z base]
(let [t (bit-and n 1), n (bit-shift-right n 1)]
(cond
(zero? t) (recur n y (* z z))
(zero? n) (* z y)
:else (recur n (* z y) (* z z))))))

(defmethod expt [::exact ::integer] [base pow]
(cond
(pos? pow) (expt-int base pow)
(zero? pow) 1
:else (/ 1 (expt-int base (- pow)))))

(defmethod expt :default [base pow] (Math/pow base pow))

expt.clj

Konrad Hinsen

unread,
Jan 1, 2009, 8:32:14 AM1/1/09
to clo...@googlegroups.com
On 01.01.2009, at 01:19, Mark Engelberg wrote:

> and pasted below. I'd like to hear some comments on whether I'm
> utilizing multimethods correctly,

I can't say, being new to multimethods as well, but...

> and whether functions like this
> would be beneficial for inclusion in the clojure contribs. If people
> find this useful, there are a few other math functions which would
> benefit from this sort of conversion as well.

... I think that this kind of routine is very useful and I'd
appreciate having it in clojure-contrib.

Konrad.

Reply all
Reply to author
Forward
0 new messages