巨大な階乗数 n! を計算するマクロ

 ワークシートでは FACT 関数を用いて

=FACT(数値)

とすれば階乗の値を返してくれますが、数値に 171 以上の値を入れるとエラーになってしまいます。エクセルでは 15 桁までの数しか扱えないからです。そこでこの問題を解決するために階乗の値を
 
\[n!=10^x\]
の形で表すことにして $x$ の部分を求めることにします。
 
\[n! = n(n - 1)(n - 2)\:\cdots\]
ですから $n$ の常用対数をとると
 
\[\log n!=\log n+\log (n-1)+\log (n -2)+\:\cdots\]
と足し算で表すことができます。まずはこの $\log n!$ を求めるプログラムを作ってみます。
 

LOGFACT 関数

 階乗の常用対数を求めるファンクションマクロ です。

 Function LOGFACT(n As Long) As Double

 Dim k As Long
 Dim logef As Double

 If n = 1 Then

  LOGFACT = 0

 'n が 1 より大きな整数であれば以下の処理を行います
 ElseIf n = Int(n) And n > 1 Then

 'n!の自然対数を計算します
  For k = 0 To n - 1
   logef = logef + Log(n - k)
  Next k

 '常用対数に変換します
  LOGFACT = logef / Log(10)

 Else

  LOGFACT = CVErr(xlErrNum)

 End If

 End Function

 たとえばワークシートのセルに

=LOGFACT(1000)

と入力すると 2567.604 ... という値が返ります。これが指数部分 $x$ に相当します。
 

n! を計算します

 n! の対数値を得ることが目的ならこのままでもいいのですが、あくまで n! の値そのものがほしい場合は別の関数を作って処理する必要があります。 $x$ を整数部分 $a$ と小数部分 $b$ に分けると
 
\[n!=10^x=10^{\,a+b}=10^{\,b} \times 10^{\,a}\]
のように書くことができます。 $10^{\,a}$ はただの桁数です。重要なのは $10^{\,b}$ のところですが、これは小さな値なので問題なく計算できます。

桁数を取り出します

 桁数 a を取り出すのには TRUNC 関数を使って

=TRUNC(LOGFACT(数値))

とするだけです。先ほどの例、つまり 1000! の桁数を得るには

=TRUNC(LOGFACT(1000))

と入力すればよく、結果は 2567 となります(ものすごい桁ですね!)。

$10^b$ を計算します

 POWERDEC という関数を作って $10^{\,b}$ を計算します。

 Function POWERDEC(x As Double) As Double
  POWERDEC = 10 ^ (x - Fix(x))
 End Function

 さきほどの 1000! の例に適用して

=POWERDEC(LOGFACT(1000))

とすると 4.0238726 ... という値を得ることができます。つまり
 
\[1000!=4.023873 \times 10^{\,2567}\]
であることがわかりました。

スポンサーリンク
末尾広告
末尾広告

コメントをどうぞ

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください