[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 interop을 사용하는 것보다 이것을 사용하는 것이 좋습니다. 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)
=> 1606938044258990275541962092341162602522202993782792835301376

패키지 설치에 대한 알림

org.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"]합니다.

lein REPL 시작 (클로저 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)
;=> 16


답변

Java Math.pow또는 BigInteger.pow메소드를 사용할 수 있습니다 .

(Math/pow base exponent)

(.pow (bigint base) exponent)


답변

이 질문이 처음에 제기되었을 때 clojure.contrib.math / expt가이 를 수행하는 공식 라이브러리 기능이었습니다. 그 이후로 clojure.math.numeric-tower 로 이동했습니다.


답변

user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376


답변

메서드가 아니라 함수가 정말로 필요한 경우 간단히 래핑 할 수 있습니다.

 (defn pow [b e] (Math/pow b e))

그리고이 함수에서 당신은 그것을 int또는 유사하게 캐스팅 할 수 있습니다 . 함수는 다른 함수에 매개 변수로 전달할 수 있기 때문에 메서드보다 종종 더 유용합니다 map.

Java interop을 피해야하는 경우 고유 한 power 함수를 작성할 수 있습니다. 예를 들어 다음은 간단한 함수입니다.

 (defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
   (if (neg? p) (/ 1 result) result)))

정수 지수 (즉, 근 없음)에 대한 검정력을 계산합니다.

또한 많은 수를 처리 하는 경우 BigInteger대신 을 사용할 수 있습니다 int.

그리고 매우 큰 숫자를 처리하는 경우 숫자 목록으로 표현하고 결과를 계산하고 결과를 다른 스트림에 출력 할 때 자신의 산술 함수를 작성하여 스트리밍 할 수 있습니다.


답변

나는 이것도 작동 할 것이라고 생각한다.

(defn expt [x pow] (apply * (repeat pow x)))