//乗算 int multiple(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c){ int i=0; int j; int k; int h=0;//桁上がりの値を一時保管 int e;//e=aj+bj+h int C;//C+=d[i] int f;//外のfor文で使う int ak,bk,tk; struct NUMBER d; struct NUMBER dtemp,ctemp; clearByZero(c); clearByZero(&d); ak=readKETA(a); bk=readKETA(b); tk=ak+bk; if(tk>KETA) return -1; if(ak==0 || bk==0){ setInt(c,0); return 0; } for(i=KETA-1;i>=KETA-tk;i--){ //for(i=0;i<tk;i++){ h=0; clearByZero(&d); for(j=KETA-1;j>=KETA-tk;j--){ e=a->n[j]*b->n[i]+h; //e=a->n[j]*b->n[KETA-1-i]+h; d.n[j]=e%10; h=e/10; if(i==0 && h!=0){ //if(i==tk && h!=0){ return -1; } } for(k=0;k<KETA-1-i;k++){ clearByZero(&dtemp); if(mulBy10(&d,&dtemp)==-1) return -1; copyNumber(&dtemp,&d); } //for(k=KETA-1;k>=KETA-tk;k--){ clearByZero(&ctemp); if(add(c,&d,&ctemp)==-1) return -1; copyNumber(&ctemp,c); //} } return 0; }
int divide(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c,struct NUMBER *d) { int k,res = 0; struct NUMBER tmp_a,n,m,l,abs_a,abs_b; copyNumber(a,&tmp_a);//aが破壊されないようにtmp_aにコピー if(isZero(b) == 0)//isZeroは0か-1が返るので return(-1); clearByZero(c); clearByZero(d);//c,dを0でクリア clearByZero(&n); clearByZero(&m); clearByZero(&l);//作業用変数n,m,lを0でクリア setInt(&n,1);//適当な変数に1を突っ込む if(numComp(b,&n) == 0)//除数が1ならば { copyNumber(a,c);//c = a; return(0); } getAbs(a,&abs_a); getAbs(b,&abs_b);//a,bの絶対値をとる if((getSign(a) == 1) && (getSign(b) == 1)) { while(1)//xから何回yを引けるか調べる { if(numComp(&tmp_a,b) == -1)//a < bならば break; copyNumber(b,&n);//bを作業用変数nに代入 setInt(&m,1);//作業用変数mに1を代入 while(1) { copyNumber(&n,&l); mulBy10(&l,&n); copyNumber(&m,&l); mulBy10(&l,&m);//mとnを10倍 if(numComp(&tmp_a,&n) == -1)//a < nならば { copyNumber(&n,&l); divBy10(&l,&n); copyNumber(&m,&l); divBy10(&l,&m);//10倍しちゃったので10で割る。いい方法を模索中、一時的に保存する? break; } } while(1) { copyNumber(&tmp_a,&l);//lに現在のaを代入 sub(&l,&n,&tmp_a);//a = l -n; すなわち a -= n; copyNumber(c,&l);//lにcを代入 add(&l,&m,c);//c = l + m;すわなち c += m; if(numComp(&tmp_a,&n) == -1) break; } } copyNumber(&tmp_a,d);//残ったtmp_aがすなわち剰余 } if((getSign(a) == 1) && (getSign(b) == -1)) { res = divide(a,&abs_b,c,d); setSign(c,-1);//+ / -は解が負であるため } if((getSign(a) == -1) && (getSign(b) == 1)) { res = divide(&abs_a,b,c,d); setSign(c,-1);//- / +は解が負であるため setSign(d,-1);//- / +は剰余が負であるため } if((getSign(a) == -1)&& (getSign(b) == -1)) { res = divide(&abs_a,&abs_b,c,d);//-x / -yは解が正であるためなにもしない setSign(d,-1);//- / -は剰余が負であるため } return(res); }
//除算(ひっ算ver.) int divide(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c,struct NUMBER *d){ struct NUMBER az,bz;//絶対値 struct NUMBER bb;//azと同じ桁数にしたbzを保管 struct NUMBER sho,amari; struct NUMBER tmp;//一時保管場所 struct NUMBER n;//n:azのコピー struct NUMBER c1,d1;//普通の除算を行うときに使う struct NUMBER bz2;//bzコピー int i=0; int ak,bk;//aとbのゼロ判定かつ桁数をみる。 int f;//aとbの桁数の差 int ch; clearByZero(c); clearByZero(d); clearByZero(&az); clearByZero(&bz); clearByZero(&bb); clearByZero(&sho); clearByZero(&amari); clearByZero(&tmp); clearByZero(&n); copyNumber(a,&az); copyNumber(b,&bz); copyNumber(&bz,&bz2); if(numComp(a,b)==-1) { return -1; } if(isZero(b)==0){ return -1; } if(isZero(a)==0){ setInt(c,0); setInt(d,0); return 0; } ak=readKETA(a); bk=readKETA(b); //bをaと桁数合わせる。 if(ak>bk){ f=ak-bk; //桁数の差を知る while(i<f){ mulBy10(&bz,&bb); copyNumber(&bb,&bz); i++; } } copyNumber(&bz,&bb); //除算実行 while(1){ //桁数を合わせたbのほうが大きい場合 //÷10して、fをデクリメント if(numComp(&az,&bb)==-1){ divBy10(&bb,&tmp); copyNumber(&tmp,&bb); f--; } //分母のほうが大きい場合 if(numComp(&az,&bz2)==-1) { break; } copyNumber(&az,&n); i=0; while(numComp(&az,&bb)==1 || numComp(&az,&bb)==0){ //az<bbになるまで繰り返す。 //ふつうの割り算アルゴリズム sub(&n,&bb,&tmp); copyNumber(&tmp,&n); copyNumber(&n,&az); i++; } c->n[KETA-1-f]=i; copyNumber(&n,&az); } copyNumber(&n,d); return 0; }
//ウォリス積の計算 //PI=4*n^2/4*n^2-1(n=1からn=kまで) int main(int argc,char **argv) { struct NUMBER num;//ウォリス積のn struct NUMBER four;//4倍するための4 struct NUMBER store;//n^2 struct NUMBER bunbo; struct NUMBER bunsi; struct NUMBER store4;//4倍したstore struct NUMBER store4_1;//4*n^2-1の計算結果を保管 struct NUMBER two;//2倍するためのもの struct NUMBER bunsix2;//2倍した値保存 struct NUMBER sho;//割り算した商 struct NUMBER amari;//わり算したあまり struct NUMBER numtemp;//numをインクリメントした値を格納する struct NUMBER hundred; struct NUMBER bunsix10; struct NUMBER dispKETA; struct NUMBER tmp; int i;//for文 int n=1; int kt;//円周率の表示 time_t start,end; start=time(NULL); srandom(time(NULL)); setInt(&four,4); setInt(&two,2); /* multiple(&four,&two,&hundred); dispNumber(&hundred); return 0; */ setInt(&hundred,100); setInt(&bunbo,1); setInt(&bunsi,1); while(n<=woris){ printf("ループ回数 %d回\n",n); setInt(&num,n);//多倍長にnをセットする if(multiple(&num,&num,&store)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1;//n^2する } if(multiple(&store,&four,&store4)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1;//4*n^2を計算 } if(decrement(&store4,&store4_1)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1;//4*n^2-1を計算 } copyNumber(&bunsi,&tmp);//tmpに分子コピー if(multiple(&tmp,&store4,&bunsi)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1;//分子と4*n^2かけ、分子に格納 } copyNumber(&bunbo,&tmp);//tmpに分母コピー if(multiple(&tmp,&store4_1,&bunbo)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1;//分母と4*n^2_1かけて分母に格納 } n++; } printf("\n"); printf("分子:"); dispNumber(&bunsi); printf("\n"); if(multiple(&bunsi,&two,&bunsix2)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1; } printf("分子x2:"); dispNumber(&bunsix2); printf("\n"); i=0; clearByZero(&tmp); while(i<disp_kt){ if(mulBy10(&bunsix2,&tmp)==-1) { printf("オーバーフローです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1; } i++; copyNumber(&tmp,&bunsix2); } copyNumber(&bunsix2,&bunsix10); printf("分子x10:"); dispNumber(&bunsix10); printf("\n"); printf("分母:"); dispNumber(&bunbo); printf("\n"); if(divide(&bunsix10,&bunbo,&sho,&amari)==-1) { printf("エラーです\n"); end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return -1; } printf("\n"); printf("商"); dispNumber(&sho); printf("\n"); /* printf("あまり"); dispNumber(&amari); printf("\n"); printf("分子x10の桁数:%d\n",readKETA(&bunsix10)); */ end=time(NULL); printf("time=%d[s]\n",(int)(end-start)); return 0; }