以前の「STM32VLDiscoveryで100の階乗計算をさせてみた」では、桁溢れのため組合せにおいて大きな数が扱えませんでした。その部分を配列を用いて改良することができたので続編として上げます。何故かできましたというレベルで、もっと良いアルゴリズムを知っている方は笑ってご覧ください。
Tera Termに表示された結果を次に示します。
あまり桁が多すぎても見辛いので、170C85に留めてありますがもっと大きな数も扱えます。ただし、
https://keisan.casio.jp/exec/system/1240796845
のサイトでは正しいかの確認ができなくなります。300C150の計算結果は次のサイトで確認できました。
https://miniwebtool.com/ja/combination-calculator/?n=300&k=150
一覧形式で出力させる機能も付け加えてみました。以下にソースを示します。これでbinのサイズは全体で16.2KBです。配列の要素数1000でも動きましたが、不安定なので500にしてあります。
#define ketaMax 500 // 配列の要素数は500個用意
void combination3(int n, int r, int a[ketaMax], int b[ketaMax]){
int k,carry;
a[0]=1; for(int i=1;i<ketaMax;i++)a[i]=0;//initialize a[]
for(k=1+n-r;k<=n;k++){ // For Example 20C10
carry=0;
for(int i=0;i<ketaMax;i++){
a[i]=a[i]*k;
a[i]=a[i]+carry;
carry=a[i]/10;
a[i]=a[i]%10;
}// permutation ends. a[0] a[11]
} // 008275244076 000000000000.........
int keta=0;
k=ketaMax-1;
while(1){
if( a[k]!= 0 ){break;}
k--;
}
keta=k+1; // 20P10 = 670442572800 keta=12
int ko=0; // combinataion begins.
int bo=0;
int wa=0;
int kb;
int num=0;
int rdigit;
bo=r;
for(bo=r;bo>1;bo--) {
for(int i=0;i<ketaMax;i++)b[i]=-1; //initialize b[]
num=bo;
rdigit=0;
while(num != 0){
num /= 10; rdigit++;
}
ko=a[keta];
kb=0;
for(k=keta;k>0;k--){
ko=ko*10+a[k-1];
wa=0;
while(ko>=bo) {
ko -= bo;
wa++;
};
b[kb]=wa;
kb++; // b[0]..b[5]
} // 184756 keta=6
for(k=0;k<ketaMax;k++){
if(k<keta)a[k]=b[keta-1-k]; // 前後入れ替え
else a[k]=0;
}
keta=0; // 桁数再計算
k=ketaMax-1;
while(1){
if( a[k]!= 0 ){keta=k+1;break;}
k--;
}
}
printf("%3dC%3d = ",n,r);
for(k=keta-1;k>=0;k--){
if(((k+1)%3) ==0){
if((k==(keta-1)) || (k==0)) {printf("%d",a[k]);
}else {
printf(",%d",a[k]);
}
}
else printf("%d",a[k]);
}
}
void combination4(int n, int r, int a[ketaMax], int b[ketaMax]){
for(int i=0;i<=n+1;i++){
combination3(n,i,a,b);printf("\r\n");
}
}
何度も書込み確認するのが面倒で、EclipseのJAVAでも同時並行で開発していました。1週間ほど悩んだ挙句、とっちらかり始め一度諦めました。ところが次の早朝3時ぐらいに目が覚め、何かいじったのでしょう、突然正しく動作するようになり結果として幸いでした。こんな事もあるのですね。それをSTM32CubeIDEに移しました。
1992~3年頃のこと、PC98に20C0~20C20(?)の計算をさせ、結果をフローッピーに書き出させるのに1日程かかっていました。ARMF1シリーズは計算器としての基本性能も高いことを再認識しました。次は、浮動小数点の計算をエミュレートできないか考えてみましょうか。