¿Cómo hacer exponenciación en clojure?



Answers

Clojure tiene una función de potencia que funciona bien: recomiendo usar esto en lugar de ir a través de la interoperabilidad de Java, ya que maneja correctamente todos los tipos de números de precisión arbitraria de Clojure.

Se llama expt para exponenciación en lugar de power o pow que tal vez explique por qué es un poco difícil de encontrar ... de todos modos aquí hay un pequeño ejemplo:

(use 'clojure.contrib.math)

(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376

A partir de Clojure 1.3, esta función y otras funciones de matemáticas relacionadas se han movido, por lo que debe hacer:

(use 'clojure.math.numeric-tower)
Question

¿Cómo puedo hacer la exponenciación en clojure? Por ahora solo estoy necesitando un exponente entero, pero la pregunta también va para las fracciones.




Tratar

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

para una solución O recursiva (log n), si desea implementarla usted mismo (solo admite enteros positivos). Obviamente, la mejor solución es usar las funciones de la biblioteca que otros han señalado.




SICP inspiró la versión rápida iterativa completa de la implementación 'sneaky' anterior.

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









Si realmente necesita una función y no un método, simplemente puede envolverla:

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

Y en esta función puedes convertirlo a int o similar. Las funciones a menudo son más útiles que los métodos, ya que puede pasarlos como parámetros a otras funciones; en este caso, el map viene a mi mente.

Si realmente necesita evitar la interoperabilidad de Java, puede escribir su propia función de encendido. Por ejemplo, esta es una función simple:

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

Eso calcula la potencia para el exponente entero (es decir, sin raíces).

Además, si se trata de números grandes , es posible que desee utilizar BigInteger lugar de int .

Y si está tratando con números muy grandes , puede expresarlos como listas de dígitos y escribir sus propias funciones aritméticas para transmitirlos a medida que calculan el resultado y emitir el resultado a alguna otra transmisión.




Links