2017-07-19 6 views
1

defmultiとdefmethodで階乗を計算しようとしました。clojure:defmultiとdefmethodを使った数の計算法

(defmulti factorial identity) 

(defmethod factorial 0 [_] 1) 

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

それはそれは私の好奇心は、我々は大きな数字のための階乗を計算するにはどうすればよい

ある階乗40

(-> 40 factorial) 

ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow 

ための整数オーバーフローの例外を示し

(-> 10 factorial) ;;3628800 

(-> 2 factorial) ;; 2 

少数のために正常に動作しますdefmultiとdefmethodを使用していますか?

+1

が重複する可能性 - (https://stackoverflow.com/questions/12826649/clojure-calculate-with-big-numbers) – cske

+1

マイナーしつこいを[Clojureのは、大きな数字で計算]: ' ( - > x階乗) 'は、広告は '(factorial x)'だけではありません。スレッディングマクロは素晴らしいですが、それらをすべて使いこなすことは過度です – cfrick

答えて

0

私はそれが数タイプの

(-> 40N factorial) ;;815915283247897734345611269596115894272000000000N 
2

の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のネイティブNumberです。 factorial関数は、ClojureScriptで最大170の結果を返します。これは、あふれたときに投げるが、JavaScript番号値Infinity返していません:

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

更新:(@cskeによって指摘)This answer*'演算子を使用するには、きちんとしたソリューションを提供します、で数値型をバンプ場合には、オーバーフローする:

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

(factorial 40) ; => 815915283247897734345611269596115894272000000000N 
関連する問題