Clojureでべき乗を実行するにはどうすればよいですか?現時点では、整数の累乗のみが必要ですが、問題は分数にも当てはまります。
Clojureでべき乗を実行するにはどうすればよいですか?現時点では、整数の累乗のみが必要ですが、問題は分数にも当てはまります。
回答:
古典的な再帰(これを見て、スタックが爆破されます)
(defn exp [x n]
     (if (zero? n) 1
         (* x (exp x (dec n)))))末尾再帰
(defn exp [x n]
  (loop [acc 1 n n]
    (if (zero? n) acc
        (recur (* x acc) (dec n)))))機能的
(defn exp [x n]
  (reduce * (repeat n x)))卑劣(スタックも吹くが、それほど簡単ではない)
(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))))))図書館
(require 'clojure.contrib.math)Clojureには、適切に機能するパワー関数があります。Clojureの任意精度の数値型をすべて正しく処理するため、Javaの相互運用機能ではなく、これを使用することをお勧めします。名前空間clojure.math.numeric-towerにあります。
それは呼ばれていますexptため、べき乗ではなく、powerまたはpow多分それは見つけることが少し難しいですなぜ...とにかく、ここで小さな例(なおだ説明している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)
=> 1606938044258990275541962092341162602522202993782792835301376org.clojure.math.numeric-towerClojure名前空間にclojure.math.numeric-towerアクセスできるようにするには、まずJavaパッケージをインストールする必要があります!
コマンドラインで:
$ lein new my-example-project
$ cd lein new my-example-project次に、依存関係ベクトルを編集project.cljして追加[org.clojure/math.numeric-tower "0.0.4"]します。
レインREPLを開始する(clojure REPLではない)
$ lein repl今:
(require '[clojure.math.numeric-tower :as math])
(math/expt 4 2)
;=> 16または
(require '[clojure.math.numeric-tower :as math :refer [expt]])
(expt 4 2)
;=> 16java Math.powまたはBigInteger.powメソッドを使用できます。
(Math/pow base exponent)
(.pow (bigint base) exponent)Math/powがいかに複雑であるmath-powかわかりません。必要なことを実行する単純なJavaメソッドがすでにある場合は、clojureで機能を再作成する理由はありません。Javaの相互運用性は本質的に有害ではありません。
                    この質問が最初に尋ねられたとき、 clojure.contrib.math / exptがこれを行う公式のライブラリ関数でした。それ以来、それはclojure.math.numeric-towerに移動しました
user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376(.pow 2M 100)
                    (Math/pow Math/E x)はトリックMath/Eを行います(選択したベースで置き換えます)。
                    メソッドではなく関数が本当に必要な場合は、単純にラップできます。
 (defn pow [b e] (Math/pow b e))この関数では、それをにキャストできますint。多くの場合、関数は別の関数にパラメーターとして渡すことができるため、メソッドよりも便利です-この場合mapます。
Javaの相互運用を回避する必要がある場合は、独自のパワー関数を作成できます。たとえば、これは単純な関数です。
 (defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
   (if (neg? p) (/ 1 result) result)))これは整数指数の指数を計算します(つまり、根がない)。
あなたが扱っている場合にも、大きな数字、あなたが使用することをお勧めしますBigInteger代わりにint。
また、非常に大きな数値を扱う場合は、それらを数字のリストとして表現し、独自の算術関数を作成して、結果を計算し、結果を他のストリームに出力するときに、それらを介してストリーミングすることができます。
clojure.math.numeric-tower以前は使用していましたclojure.contrib.math。
(ns user
  (:require [clojure.math.numeric-tower :as m]))
(defn- sqr
  "Uses the numeric tower expt to square a number"
  [x]
  (m/expt x 2))reduceを使用した単純なワンライナー:
(defn pow [a b] (reduce * 1 (repeat b a)))clojure.contrib.genric.math-functionsはどうですか
clojure.contrib.generic.math-functionsライブラリには、pow関数があります。これは、Math.powの単なるマクロであり、Java数学関数を呼び出すためのより「奇妙な」方法です。