Comment faire de l'exponentiation dans clojure?
Comment puis-je faire exponentiation en clojure?
Pour l'instant je suis le seul à en avoir besoin entier élévation à la puissance, mais la question vaut pour les fractions de trop.
- Comme quelqu'un qui ne sait pas clojure, mais il est prédisposé à aimer ça (étant un fan de lisps, la programmation fonctionnelle, et avoir beaucoup de pratique des bibliothèques), je suis déçu que cette simple question a donc beaucoup de réponses, ni que cela a dû être demandé à tous. J'aurais pensé que l'exponentiation serait juste l'une des fonctions de base sans avoir à faire quoi que ce soit de spécial. Je suis heureux, il a été demandé, si.
- eh bien oui, probablement une version de celui-ci devrait être à la base... mais je pense que beaucoup de réponses, c'est toujours un bon signe. les "chemins d'accès multiples à la mise en œuvre" semble être la raison pour laquelle beaucoup de ces choses ne sont pas fournis-l'utilisateur doit connaître les détails de la fonction qu'ils utilisent pour des raisons d'efficacité. par exemple (comme il est indiqué dans la réponse choisie) certains égards, il peut potentiellement coup de la pile, d'autres le sont moins susceptibles de le faire. peut-être que certains sont paresseux, enthousiastes... tous les détails qui doivent être payés à un peu d'attention en Clojure, qui est pourquoi je pense que la plupart des non-trivial libs ne sont pas fournies en raison de la philosophie
- Je pense que la raison il n'y a pas seulement une fonction exp dans le cœur est parce que clojure numérique de la tour est mal rompu pour des raisons d'efficacité. Donc, il ya toutes sortes de choses que vous pourriez dire par exponentiation. Ce qui devrait (exp 2 (exp 2 200)) être? Une erreur ou d'un énorme entier qui prend du temps à calculer? Si vous voulez juste l'habitude de virgule flottante exp, puis le java est construit en. Si vous voulez une langue où les chiffres font de leur mieux pour agir comme le corps des réels, et accrocher le coût, l'utilisation de régime au lieu de clojure.
Vous devez vous connecter pour publier un commentaire.
classique de la récursivité (regardez cela, il souffle sur la pile)
queue de récursivité
fonctionnelle
sournois (aussi coups de pile, mais pas si facilement)
bibliothèque
(def exp (letfn [(rexp [x n r] (cond (zero? n) r (even? n) (recur (*' x x) (/ n 2) r) :else (recur (*' x x) (/ (dec n) 2) (*' x r))))] (fn [x n] (rexp x n 1))))
. Il n'a jamais fait sauter la pile. Test(exp 1 (exp 2 30000))
Clojure a une fonction de puissance qui fonctionne bien: je vous recommande d'utiliser le présent, plutôt que de passer par Java interop puisqu'il gère l'ensemble de la Clojure précision arbitraire des types de numéro correctement.
Il est appelé
expt
pour exponentiation plutôt quepower
oupow
qui explique peut-être pourquoi il est un peu difficile à trouver ... en tout cas voici un petit exemple:Vous pouvez utiliser java
Math.pow
ouBigInteger.pow
méthodes:Math/pow
est plus compliqué quemath-pow
ou quel que soit le nom serait si il y avait un clojure équivalent. Si il y a déjà une simple méthode java qui fait ce que vous voulez, il n'y a pas de raison de recréer les fonctionnalités en clojure. Java interopérabilité n'est pas intrinsèquement nocifs.No matching method pow ... for class clojure.lang.BigInt
-- ne devrait-elle pas être(.pow (biginteger base) exponent)
?Lorsque cette question a été initialement demandé, clojure.contrib.math/expt était la langue officielle de la bibliothèque de fonction pour ce faire. Depuis, il a déménagé à clojure.les mathématiques.numérique-tour
(.pow 2M 100)
(Math/pow Math/E x)
fait le tour (en remplacement deMath/E
avec la base de votre choix).Si vous avez vraiment besoin d'une fonction et non pas une méthode, vous pouvez simplement envelopper:
Et dans cette fonction, vous pouvez le convertir en
int
ou similaire. Les fonctions sont souvent plus utiles que les méthodes parce que vous pouvez passer en paramètres à une autre des fonctions - dans ce casmap
vient à mon esprit.Si vous avez vraiment besoin pour éviter de Java interop, vous pouvez écrire votre propre fonction de la puissance. Par exemple, c'est une fonction simple:
Qui calcule la puissance pour l'entier de l'exposant (c'est à dire pas de racines).
Aussi, si vous traitez avec grand numéros, vous pouvez utiliser
BigInteger
au lieu deint
.Et si vous avez affaire avec très grande numéros, vous pouvez exprimer sous forme de listes de chiffres, et d'écrire vos propres fonctions mathématiques pour les flux au-dessus d'eux, comme ils calculer le résultat et la sortie de la suite à certains autres flux.
Je pense que ce serait trop de travail:
SICP inspiré plein itératif rapide version de "sournois" de mise en œuvre ci-dessus.
Utilisation
clojure.les mathématiques.numérique-tour
, anciennementclojure.contrib.math
.La Documentation de l'API
Mise en œuvre de "sournois" la méthode avec la queue de la récursivité et de soutien de l'exposant négatif:
Un simple one-liner à l'aide de réduire:
Essayer
pour une queue-récursive O(log n) solution, si vous voulez mettre en œuvre vous-même (prend en charge uniquement les entiers positifs). Évidemment, la meilleure solution est d'utiliser les fonctions de la bibliothèque que d'autres l'ont souligné.
Comment sur clojure.contrib.genric.mathématiques-fonctions
Il y a une fonction pow dans le clojure.contrib.génériques.mathématiques-fonctions de la bibliothèque. C'est juste une macro pour les Mathématiques.pow et est plus un "clojureish" de l'appel de la Java de fonction mathématique.
http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow