On Thu, 15 Jul 2010 04:38:22 -0700 (PDT) Brisance <cru...@gmail.com> wrote:
> Here's a factorial function as found in the WikiBook "Learning > Clojure" <http://en.wikibooks.org/wiki/Learning_Clojure>: > > (defn factorial [n] > (defn fac [n acc] > (if (zero? n) > acc > (recur (- n 1) (* acc n)))) ; recursive call to fac, but reuses > the stack; n will be (- n 1), and acc will be (* acc n) > (fac n 1)) > > Question: how would I go about writing idiomatic Clojure to return > factorials of n, for large values of n. e.g. 1e6 or more? Preferably > without having to create another function. Well, an idiomatic refactoring of the above might be: (defn factorial [n] (reduce * (range 1 (inc n))) However, that won't be able to calculate 1000000! on my hardware, as that has over five and a half billion digits, and I only have 4Gig of ram. If you actually want to see the value - well, that's a lot of paper. Or phosphor, or whatever. If you'll settle for an seeing an approximation, this works: (defn fact-approx "Approximate factorial values as strings representing floats. We output strings since we can build the string for output values to large to be represented in floats. Works for n less than 10 billion." [n] (apply (fn [val exp] (let [valstr (str val)] (str (subs valstr 0 (min 6 (count valstr))) "E" exp))) (let [x (+ n n 1) ex 0.0] (if (> x 1) (let [t (/ (- (+ (Math/log (* 2.0 Math/PI)) (* (Math/log (/ x 2.0)) x)) x (/ (- 1.0 (/ 7.0 (* 30.0 x x))) (* 6.0 x))) 2.0 (Math/log 10)) ex (int t)] [(Math/pow 10 (- t ex)), ex] ) [x, 0])))) It's not clear you'd call it idiomatic; I haven't seen enough hard-core mathematical calculations to have a feel for what would be considered idiomatic. If you really need to work with accurate values of n! for these values of n (and have the hardware to deal with them), googling for "fast factorial" turns up some Java objects that might be of interest. <mike -- Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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 Note that posts from new members are moderated - please be patient with your first post. 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