Jak zrobić wykładnik w clojure?
Jak zrobić wykładnik w clojure? Na razie potrzebuję tylko wykładnika liczby całkowitej, ale pytanie dotyczy też ułamków.
13 answers
Rekurencja Klasyczna (patrz na to, wieje stos)
(defn exp [x n]
(if (zero? n) 1
(* x (exp x (dec n)))))
Rekurencja ogona
(defn exp [x n]
(loop [acc 1 n n]
(if (zero? n) acc
(recur (* x acc) (dec n)))))
Funkcjonalne
(defn exp [x n]
(reduce * (repeat n x)))
Sneaky (również wieje stack, ale nie tak łatwo)
(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))))))
Biblioteka
(require 'clojure.contrib.math)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-20 17:42:27
Clojure ma funkcję mocy, która działa dobrze: zalecałbym jej używanie, a nie przechodzenie przez Java interop, ponieważ obsługuje wszystkie typy liczb arbitralnie precyzyjnych Clojure poprawnie.
Nazywa się expt
dla wykładnik zamiast power
lub pow
, co może wyjaśniać, dlaczego jest trochę trudne do znalezienia..... w każdym razie oto mały przykład:
(use 'clojure.contrib.math)
(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376
Od Clojure 1.3 funkcja Ta i inne powiązane funkcje matematyczne zostały przeniesione, więc musisz zrobić:
(use 'clojure.math.numeric-tower)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-13 18:25:57
Możesz użyć metod Javy Math.pow
lub BigInteger.pow
:
(Math/pow base exponent)
(.pow (bigint base) exponent)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-20 13:02:48
Kiedy to pytanie zostało pierwotnie zadane, http://clojure.github.com/clojure-contrib/math-api.html#clojure.contrib.math/expt to miejsce, w którym funkcjonowała oficjalna biblioteka. Od tego czasu przeniósł się do https://github.com/clojure/math.numeric-tower/blob/master/src/main/clojure/clojure/math/numeric_tower.clj#L80
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-26 23:53:04
user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-27 13:54:21
Jeśli naprawdę potrzebujesz funkcji, a nie metody, możesz ją po prostu owinąć:
(defn pow [b e] (Math/pow b e))
I w tej funkcji można go wrzucić do {[2] } lub podobnego. Funkcje są często bardziej użyteczne niż metody, ponieważ można je przekazać jako parametry innym funkcjom-w tym przypadku przychodzi mi do głowy map
.
Jeśli naprawdę chcesz uniknąć Java interop, możesz napisać własną funkcję power. Na przykład jest to prosta funkcja:
(defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
(if (neg? p) (/ 1 result) result)))
Który oblicza moc dla wykładnika całkowitego (tj. bez korzeni).
Ponadto, jeśli masz do czynienia z dużymi liczbami , możesz użyć BigInteger
zamiast int
.
A jeśli masz do czynienia z bardzo dużymi liczbami, możesz wyrazić je jako listy cyfr i napisać własne funkcje arytmetyczne, aby przesyłać je strumieniowo, gdy obliczają wynik i wysyłają wynik do innego strumienia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-20 14:00:46
Myślę, że to też by zadziałało:
(defn expt [x pow] (apply * (repeat pow x)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-12 07:56:41
SICP inspired Pełna iteracyjna szybka wersja' podstępnej ' implementacji powyżej.
(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)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-10 02:41:58
Użycie clojure.math.numeric-tower
, dawniej 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))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-30 18:10:26
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)))))
Dla rekurencyjnego rozwiązania o(log n), jeśli chcesz zaimplementować je samodzielnie (obsługuje tylko dodatnie liczby całkowite). Oczywiście lepszym rozwiązaniem jest użycie funkcji bibliotecznych, które wskazywali inni.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-29 22:21:44
Implementacja metody "sneaky" z rekurencją ogonową i wsparciem wykładnika ujemnego:
(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)))))))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-06 13:53:00
A może clojure?contrib.genric.matematyka-funkcje
Istnieje funkcja pow w clojure.contrib.ogólne.biblioteka funkcji matematycznych. To tylko makro do matematyki.pow i jest bardziej "clojureish" sposobem wywoływania funkcji matematycznej Javy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-20 21:13:26
A simple one-liner using reduce
(defn pow [a b] (reduce * 1 (repeat b a)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-11 11:41:18