Programing

클로저에서 지수화하는 방법은 무엇입니까?

lottogame 2020. 8. 22. 11:29
반응형

클로저에서 지수화하는 방법은 무엇입니까?


클로저에서 지수화하려면 어떻게해야합니까? 지금은 정수 지수화 만 필요하지만 문제는 분수에도 적용됩니다.


고전적인 재귀 (이것을보세요, 그것은 스택을 날려 버립니다)

(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을 사용하는 것보다 이것을 사용하는 것이 좋습니다.

그것은라고 expt를 위해 지수 보다는 power또는 pow어떤 어쨌든 여기 ... 찾기 위해 조금 어렵 작은 예를 왜 어쩌면 설명 :

(use 'clojure.math.numeric-tower)  ; as of Clojure 1.3
;; (use 'clojure.contrib.math)     ; before Clojure 1.3

(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376

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.

And if you are dealing with very large numbers, you may want to express them as lists of digits, and write your own arithmetic functions to stream over them as they calculate the result and output the result to some other stream.


I think this would work too:

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

SICP inspired full iterative fast version of 'sneaky' implementation above.

(defn fast-expt-iter [b n]
  (let [inner (fn [a b n]
                (cond
                  (= n 0) a
                  (even? n) (recur a (* b b) (/ n 2))
                  :else (recur (* a b) b (- n 1))))
        ]
    (inner 1 b n)))

Use clojure.math.numeric-tower, formerly clojure.contrib.math.


API Documentation


(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))

Implementation of "sneaky" method with tail recursion and supporting negative exponent:

(defn exp
  "exponent of x^n (int n only), with tail recursion and O(logn)"
   [x n]
   (if (< n 0)
     (/ 1 (exp x (- n)))
     (loop [acc 1
            base x
            pow n]
       (if (= pow 0)
         acc                           
         (if (even? pow)
           (recur acc (* base base) (/ pow 2))
           (recur  (* acc base) base (dec pow)))))))

A simple one-liner using reduce:

(defn pow [a b] (reduce * 1 (repeat b a)))

Try

(defn pow [x n]
  (loop [x x n n r 1]
    (cond
      (= n 0) r
      (even? n) (recur (* x x) (/ n 2) r)
      :else (recur x (dec n) (* r x)))))

for a tail-recursive O(log n) solution, if you want to implement it yourself (only supports positive integers). Obviously, the better solution is to use the library functions that others have pointed out.


How about clojure.contrib.genric.math-functions

There is a pow function in the clojure.contrib.generic.math-functions library. It is just a macro to Math.pow and is more of a "clojureish" way of calling the Java math function.

http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow

참고URL : https://stackoverflow.com/questions/5057047/how-to-do-exponentiation-in-clojure

반응형