□2000個から1000個選ぶ!巨大組合せ計算式
2000個から1000個選ぶ組合せは2.05×10の600乗
順列組合せの値はあっという間にとんでもなく大きな値となります。
例えば、2000個から1000個選ぶといったごく普通の数値で
- 2.05×10の600乗
日本の人口約1億3千万から半数を選ぶ方法は
- 10の約4千万乗
- 10の約5億乗
順列組合せの計算は単純な掛け算(と割り算)のみを多数回行います。
掛け合わせる数が多いので整数演算ではすぐにオーバーフローしてしまいます。
浮動小数演算でも桁は限られます。
どうするか?
簡単です。対数計算にすればよいのです。
冒頭の計算機は次のように計算を行っています。戻り値は自然対数で、 表示時に10の対数化しています。
function calcP(n,r){ var p = 0; for(var i=0;i<r;++i) p += Math.log(n--); return p;// Math.LOG10Eをかけると10の対数が得られる } function calcC(n,r){ var rr= Math.min(r,n-r); var p = 0; for(var i=1;i<=rr;++i) p = p+Math.log(n--)-Math.log(i); return p;// Math.LOG10Eをかけると10の対数が得られる }
次のようにして結果の文字列を得ています。
function disp(p){ var pp=p * Math.LOG10E;// 10の対数化 if( pp<5 ) return Math.round(Math.exp(p));// 5桁以下は通常表示 var e= Math.floor(pp); var m= pp-e; return Math.pow(10,m).toFixed(5)+"×10の"+e+"乗"; }なお、組合せの計算は順列値を階乗で割る形でも構いません。
function calcC(n,r){ var rr= Math.min(r,n-r); var p = calcP(n,rr); for(var i=2;i<=rr;++i) p -= Math.log(i); return p; }
###
本記事のプログラムは以前の記事 ◆順列組合せの公式はΠ(総乗)を使うべき の掛け算割り算を単純に対数の+-に置き換えたものです。
| 固定リンク