Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在clojure中执行幂运算?_Clojure_Exponentiation - Fatal编程技术网

如何在clojure中执行幂运算?

如何在clojure中执行幂运算?,clojure,exponentiation,Clojure,Exponentiation,如何在clojure中执行幂运算? 现在我只需要整数求幂,但问题也涉及分数 您可以使用java的Math.pow或biginger.pow方法: (Math/pow base exponent) (.pow (bigdec base) exponent) 如果您真的需要函数而不是方法,您可以简单地包装它: (defn pow [b e] (Math/pow b e)) 在这个函数中,您可以将其强制转换为int或类似。函数通常比方法更有用,因为您可以将它们作为参数传递给另一个函数——在这种

如何在clojure中执行幂运算?
现在我只需要整数求幂,但问题也涉及分数

您可以使用java的
Math.pow
biginger.pow
方法:

(Math/pow base exponent)

(.pow (bigdec base) exponent)

如果您真的需要函数而不是方法,您可以简单地包装它:

 (defn pow [b e] (Math/pow b e))
在这个函数中,您可以将其强制转换为
int
或类似。函数通常比方法更有用,因为您可以将它们作为参数传递给另一个函数——在这种情况下,我想到了
map

如果确实需要避免Java互操作,可以编写自己的power函数。例如,这是一个简单的函数:

 (defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
   (if (neg? p) (/ 1 result) result)))
计算整数指数的幂(即无根)

此外,如果您处理的是大数,您可能希望使用
biginger
而不是
int


如果您处理的是非常大的数字,您可能希望将它们表示为数字列表,并编写自己的算术函数,在它们计算结果并将结果输出到其他流时对其进行流式处理。

clojure.contrib.genric.math-functions如何

clojure.contrib.generic.math-functions库中有一个pow函数。它只是Math.pow的一个宏,更像是调用Java数学函数的“clojureish”方式


最初提出这个问题时,是由官方图书馆职能部门来做的。从那时起,它就转移到了经典递归(注意这一点,它破坏了堆栈)

尾部递归

(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)))
鬼鬼祟祟(也吹烟囱,但不那么容易)

图书馆

(require 'clojure.contrib.math)

Clojure有一个强大的功能,可以很好地工作:我建议使用它,而不是通过Java互操作,因为它可以正确地处理所有Clojure任意精度的数字类型。它位于命名空间中

它被称为求幂的
expt
,而不是
power
pow
,这也许可以解释为什么要找到它有点困难。。。无论如何,这里有一个小例子(请注意,
use
有效,但更好地使用):

软件包安装提示 您必须首先安装Java包
org.clojure.math.numeric tower
,才能访问clojure命名空间
clojure.math.numeric tower

在命令行上:

$ lein new my-example-project
$ cd lein new my-example-project
然后编辑
project.clj
并将
[org.clojure/math.numeric-tower“0.0.4”]
添加到依赖项向量中

启动lein REPL(不是clojure REPL)

现在:


我认为这也会起作用:

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

对于尾部递归O(logn)解决方案,如果您想自己实现它(只支持正整数)。显然,更好的解决方案是使用其他人指出的库函数。

上面“偷偷”实现的完整迭代快速版本

user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376
(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)))
使用,以前是
clojure.contrib.math



带尾部递归和支持负指数的“偷偷摸摸”方法的实现:

(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)))))))
(defn exp
x^n(仅整数n)的指数,带尾部递归和O(logn)
[xN]
(如果(
使用reduce的简单单行程序:

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

+1,尽管我知道您可以与java libs进行互操作;然而,1)Math.pow与double一起工作,我需要整数,你能举个例子吗?2) 你真的要用互操作来完成一些简单的事情吗?比如说异能?@Peter:1)除非你的异能太大,以至于不能用双倍数字来精确表示,将结果转换为int确实没有问题。2)我不认为编写
Math/pow
Math-pow
或者如果有clojure等价物的话会是什么名字更复杂。如果已经有一个简单的java方法可以满足您的需要,那么就没有理由在clojure中重新创建该功能。Java互操作并不是天生有害的。@Da vinci:奇怪的是,它是自己的语言,有很多Java函数(比如stringreverse)。如果你想要精确的大整数幂,我认为最好使用Clojure的Clojure.contrib.math/expt。可能在幕后也会做同样的事情,但比通过Java互操作要好得多……我得到的是
没有匹配的方法pow。。。对于clojure.lang.BigInt类
——这个答案不应该是
(.pow(biginteger基)指数)
?+1,因为它正确处理了所有clojure精确(即BigDecimal/biginteger)算法。;此链接唯一的答案现在有误导性。但似乎最大值为2^63。。。def不支持2^200可能未知,因为它似乎不是标准Clojure的一部分。当我尝试这样做时,1.3.0抛出了关于无法定位math.clj的错误。我认为从1.3开始,它现在位于“clojure.math.numeric tower”中(因为clojure.contrib被分解为各个库),添加了“关于包安装的提醒”,以减轻用户的沮丧。作为不了解clojure的人,但是我倾向于喜欢它(作为lisps、函数式编程的爱好者,并且拥有很多方便的库),我很失望这个简单的问题有这么多的答案——或者根本不需要问它。我原以为幂运算只是提供的基本函数之一,不需要做任何特殊的事情。不过,我很高兴有人问这个问题。是的,也许它的某些版本应该在核心中。。。但我认为许多答案仍然是一个好迹象。“实现的多条路径”似乎是很多东西没有提供的原因——为了提高效率,用户应该知道他们正在使用的函数的细节。例如(正如所选答案中所指出的),某些方式可能会使t
(require '[clojure.math.numeric-tower :as math])
(math/expt 4 2)
;=> 16
(require '[clojure.math.numeric-tower :as math :refer [expt]])
(expt 4 2)
;=> 16
(defn expt [x pow] (apply * (repeat pow x)))
(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)))))
user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376
(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)))
(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))
(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)))))))
(defn pow [a b] (reduce * 1 (repeat b a)))