0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

STM32VLDiscoveryに大きな数になる組合せを計算させる(配列編)

Last updated at Posted at 2023-03-06

 以前の「STM32VLDiscoveryで100の階乗計算をさせてみた」では、桁溢れのため組合せにおいて大きな数が扱えませんでした。その部分を配列を用いて改良することができたので続編として上げます。何故かできましたというレベルで、もっと良いアルゴリズムを知っている方は笑ってご覧ください。
 Tera Termに表示された結果を次に示します。
32Cx.jpg
あまり桁が多すぎても見辛いので、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シリーズは計算器としての基本性能も高いことを再認識しました。次は、浮動小数点の計算をエミュレートできないか考えてみましょうか。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?