¿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.




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.




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






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.