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)) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
expt.clj
Description: Binary data