【问题标题】:clojure: Compute Factorial of number using defmulti and defmethodclojure:使用 defmulti 和 defmethod 计算数字的阶乘
【发布时间】:2017-07-19 14:22:45
【问题描述】:

我尝试通过 defmulti 和 defmethod 计算阶乘。

(defmulti factorial identity)

(defmethod factorial 0 [_] 1)

(defmethod factorial :default [num]
  (* num (factorial (dec num))))

它适用于小数字

(-> 10 factorial) ;;3628800

(-> 2 factorial) ;; 2

它显示阶乘 40 的整数溢出异常

(-> 40 factorial)

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow

我的好奇心是

我们如何使用 defmulti 和 defmethod 计算大数的阶乘?

【问题讨论】:

  • 轻微唠叨:(-> x factorial)(factorial x) 更难阅读。线程宏很棒,但在所有事情上都使用它们是大材小用

标签: clojure


【解决方案1】:

Clojure 的数字类型实现建立在主机平台的数字类型之上。 Your solution 在您定义 任意大小 标志 N 时起作用,因为基础数字类型在 JVM 上发生了变化。

(type 10)  ;=> java.lang.Long
(type 10N) ;=> clojure.lang.BigInt

clojure.lang.BigIntuses either java.math.BigInteger or a Java long as the underlying type,取决于数字的位大小。

在不同的主机上,浏览器的 Javascript 引擎,这两种类型都是 JavaScript 的原生 Numbers。 factorial 函数在 ClojureScript 中给出的结果最多为 170。溢出时不抛出,而是返回JavaScript数值Infinity

(factorial 170)  ; => 7.257415615307994e+306
(factorial 170N) ; => 7.257415615307994e+306
(factorial 171N) ; => Infinity

更新:This answer(由@cske 指出)提供了一个使用*' 运算符的简洁解决方案,它会增加数字类型以防溢出:

(defmethod factorial :default [num]
  (*' num (factorial (dec num))))

(factorial 40) ; => 815915283247897734345611269596115894272000000000N

【讨论】:

    【解决方案2】:

    我已经解决了

    (-> 40N factorial) ;;815915283247897734345611269596115894272000000000N
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      • 2014-02-25
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      相关资源
      最近更新 更多