클로저에서 지수화하려면 어떻게해야합니까? 지금은 정수 지수화 만 필요하지만 문제는 분수에도 적용됩니다.
답변
고전적인 재귀 (이것을보세요, 그것은 스택을 날려 버립니다)
(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-tower
Clojure 네임 스페이스에 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)))