Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

スターリングの近似の精度をあげる

$
0
0

たまには数学の記事を書かないとね。

いまどきの学生さんは、階乗とか習うのかな?

数IIICの確率統計で、順列とか組み合わせの計算に階乗が使われる。

n! = n*(n-1)*…*3*2*1 = Π{k=1, n} k
n > 0

例えば、

5! = 5*4*3*2*1 = 120

である。

また便宜上、

0! = 1

と定義されている場合があります。


例えば、Windows付属の電卓で階乗の計算をしてみましょう。

表示(V)→関数電卓(S)

で、関数電卓にします。


では、

3249!

を計算してみてください。

おそらく、計算できなかったと思われますので、1減らしてみましょう。

3248!

を計算してみてください。

1.9736342530860425312047080034031e+9997

と出たかと思います。

有効桁数32桁、10の冪乗の指数は9997、おそらく10000以下まで対応なのでしょう。

細かく調べてみると、

3248.7701987264017464094989989231

が限界でした。


さて、もっと大きなnにおける階乗の値を求めたいとすると、多倍長演算プログラムなどで計算することになるだろう。

だとしても、nの値が大きくなるにつれ、計算時間が長くなってしまう。

どのみち、桁数は膨大になるので、有効桁数何桁まで解ればいいということで、もっと簡単に求める方法はないものかということで、近似式というものを使います。


スターリングの近似式

n! ~ √(2nπ) * (n/e)^n

というものがあり、私のブログでも度々登場していたかとは思います。

実は、この式は、数列の第1項までで、

n! ~ √(2nπ) * (n/e)^n * {

+1
+1/(12*n^1)
+1/(288*n^2)
-139/(51840*n^3)
-571/(2488320*n^4)
+163879/(209018880*n^5)
+5246819/(75246796800*n^6)
-534703531/(902961561600*n^7)
-4483131259/(86684309913600*n^8)
+432261921612371/(514904800886784000*n^9)
+6232523202521089/(86504006548979712000*n^10)
-25834629665134204969/(13494625021640835072000*n^11)
-1579029138854919086429/(9716130015581401251840000*n^12)
+746590869962651602203151/(116593560186976815022080000*n^13)
+1511513601028097903631961/(2798245444487443560529920000*n^14)
-8849272268392873147705987190261/(299692087104605205332754432000000*n^15)
-142801712490607530608130701097701/(57540880724084199423888850944000000*n^16)
+2355444393109967510921431436000087153/(13119320805091197468646658015232000000*n^17)
+2346608607351903737647919577082115121863/(155857531164483425927522297220956160000000*n^18)
-2603072187220373277150999431416562396331667/(1870290373973801111130267566651473920000000*n^19)
-73239727426811935976967471475430268695630993/(628417565655197173339769902394895237120000000*n^20)

}

の様に、{}内の数列の項数を増やすことで精度が上がっていきます。

現在ネットを探すと、上記の項まで見つけることができる。
もしかすると、もっとあるかもしれません。

この式との比較をしてみる。
前者が正しい値、後者は近似値で10項から項数を減らして、必要であれば小数点以下65桁目を切り捨てます。

10! =
3628800
3628800.0000000413287222259077132059941756592087603463951148463286755252
3628799.9999970202283542045624956056420760836554392130130323907654319407
3628799.9999988813984824647740926569380074749829129413885573007095214822
3628800.0002119840748494874034964368012673834926005622128979231528544137
3628799.9999610537316242031166674326684999513118938985033711483298531461
3628799.9717458686103728488945184837938277992839130530820333830310980273
3628800.0543258904042390522464520557478167240314446629764704112524986045
3628809.7036061952847173143147671534188168276309350520427375267198305003
3628684.7488972112209700357322694857368010975655918842781273983658922809
3598695.6187410359216231759328292420530258818832316207716965934207196174

ここからは、桁数が膨大になるため、指数表記します。

100! =
9.3326215443944152681699238856266700490715968264381621468592963895e+157
9.3326215443944152681699189532743149890118458856354832682579910123e+157
9.3326215443944152681620907556224392242232869379788479449666843912e+157
9.3326215443944152682103169177917225871787232628059863331202686129e+157
9.3326215443944153234289348890097197878119750975243646747508219791e+157
9.3326215443944146732246767275769892733107919927090412119498739551e+157
9.3326215443936835685971992888393496684725276605309776323150125864e+157
9.3326215444150814916699101740730562486094032996236261922931004986e+157
9.3326215694180486967709655644916731791232849154119260476000269235e+157
9.3326183316237343671378934239513512420738670435457577344728639785e+157
9.3248476252693432477647561271787023234709745647418062292817958153e+157

1000! =
4.0238726007709377354370243392300398571937486421071463254379991042e+2567
4.0238726007709377354370243392300395750055375426031241674108323717e+2567
4.0238726007709377354370243392266618205962962354958780208022224975e+2567
4.0238726007709377354370243394347507564563286011863772028566523514e+2567
4.0238726007709377354370267220384945416024284386669367973946814776e+2567
4.0238726007709377354367461682766224202872377254809665797169356725e+2567
4.0238726007709377322821351212664448547241796071618881033925708079e+2567
4.0238726007709386555716612887202171786126557819999090726554804282e+2567
4.0238726007817270753940592774574238054305866388754028066887324579e+2567
4.0238725868111114780441458048157487894050165842792004614702768379e+2567
4.0235372920367750801208024046153641757237062754229152185353988880e+2567

3249! =
6.41233768827655218388409630305681276918787272053336586922008544864e+10000
6.41233768827655218388409630305681276918437673747736423249289328004e+10000
6.41233768827655218388409630305681263574688107877135876252214432123e+10000
6.41233768827655218388409630305683934418634959343887230116972367556e+10000
6.41233768827655218388409630405041525964641827856837319530927028069e+10000
6.41233768827655218388409592393538418823413087058505555639237102604e+10000
6.41233768827655218387020937022666846787869528895989235791705774701e+10000
6.41233768827655219707514470125534081366574950724439214297548468837e+10000
6.41233768827705350655743804119902584937931086748809904493690677133e+10000
6.41233768616787500702656706374663314430769433709478677818249988081e+10000
6.41217322086519558783122923597306247993712038817747433655080421024e+10000

10000! =
2.8462596809170545189064132121198688901480514017027992307941799942e+35659
2.8462596809170545189064132121198688901480513812504566916917683925e+35659
2.8462596809170545189064132121198688901456619698014713152164745969e+35659
2.8462596809170545189064132121198688916176756970008553512009758610e+35659
2.8462596809170545189064132121200374361586352152529760406995468234e+35659
2.8462596809170545189064132119215747033918275998964302196017021955e+35659
2.8462596809170545189063908963152884697720459273551406311392039104e+35659
2.8462596809170545189717040688336043820736917618070118907434085275e+35659
2.8462596809170621506614946503356512573978154550652269389606661881e+35659
2.8462596808182345130856190842610067723427948450861852766312486112e+35659
2.8462359621852163029497611695845935673963998750872262164127785047e+35659

100000! =
2.8242294079603478742934215780245355184774949260912248505789180865e+456573
2.8242294079603478742934215780245355184774949260912248485446327120e+456573
2.8242294079603478742934215780245355184774949260888539135455455027e+456573
2.8242294079603478742934215780245355184774949406951657165454935026e+456573
2.8242294079603478742934215780245355184942190654262034134385359380e+456573
2.8242294079603478742934215780245353215661264461646834636343861683e+456573
2.8242294079603478742934215778031048433939862388118583798333201021e+456573
2.8242294079603478742934280586160552815421964859468295685352293691e+456573
2.8242294079603478818661047670789843286120536711956945665439690827e+456573
2.8242294079593672474722030928138961456672013001887581829839453972e+456573
2.8242270544368218834539668811748284999767846528682141261388402815e+456573

スターリングの近似式は、nが大きくなるにつれ、絶対誤差も大きくなるのだが、相対誤差は小さくなる。

つまり、Windowsの電卓の有効桁数32桁は、3249!以上は9項までを含めれば近似式で問題なくカバーできているであろう。


数学のテクニックとして、上記式を、

n! ~ (2nπ)^(1/2) * (n/e)^n * {m}

として、両辺のlog10を取る。

log10(n!) ~ log10(2nπ)/2 + n*log10(n/e) + log10(m)

※log10を取ると、指数は乗算に、乗算は加算になります。

l = log10(2nπ)/2 + n*log10(n/e) + log10(m)
y = floor(l)
x = l-y

つまり、yはlの整数部、xはlの小数部とすれば、
指数表記の仮数部は10^x、指数部はyである。

プログラミングで多倍長演算を実装して独自に指数表示をするような場合には、知っていなければならないだろう。



Viewing all articles
Browse latest Browse all 5376

Trending Articles