コード例 #1
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//乗算
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;
  
}
コード例 #2
0
ファイル: enshu5.c プロジェクト: mimter/Integer
int sub(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c)
{
	int i,h=0,d=0;
	struct NUMBER temp;
	clearByZero(&temp);
	clearByZero(c);
	if(getSign(a)==1)
	{
		if(getSign(b)==1)
		{
			for(i=0;i<KETA;i++)
			{
				if(numComp(a,b)==1)
				{
					d=a->n[i]-b->n[i]-h;
					h=0;
					if(d<0)
					{
						d+=10;
						h=1;
					}
					c->n[i]=d;
				}
				else
				{
					getAbs(b,&temp);
					sub(&temp,a,c);
					setSign(c,-1);
				}

			}
		}
		else if(getSign(b)==-1)
		{
			getAbs(b,&temp);
			add(a,&temp,c);
		}
	}
	else if(getSign(a)==-1)
	{
		if(getSign(b)==1)
		{
			getAbs(a,&temp);
			add(b,&temp,c);
			setSign(c,-1);
		}
		else if(getSign(b)==-1)
		{
			getAbs(b,&temp);
			add(&temp,a,c);
		}
	}

	return 0;
}
コード例 #3
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//減算
int sub(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c){

  int h=0;//桁下がりみてる
  int i;
  int cha,chb;//構造体が正か負か確認引数
  int flag;
  struct NUMBER d;//絶対値をとる
  struct NUMBER e,f;//大小比較するためのe>f

  clearByZero(c); 
  clearByZero(&e);
  clearByZero(&f);

  

  if(numComp(a,b)==1){    //大きいほうをe小さいほうをf
    copyNumber(a,&e); 
    copyNumber(b,&f);
    setSign(c,1);  
  }
  if(numComp(a,b)==-1){  //上に同じく
    copyNumber(b,&e);
    copyNumber(a,&f);
    setSign(c,-1);
  }
  if(numComp(a,b)==0){
    setInt(c,0);
    setSign(c,1);
    return 1;
  }

  for(i=KETA-1;i>-1;i--){
    e.n[i]=e.n[i]-h; //aiからhを引く
    if(e.n[i] >= f.n[i]){//ai>=biならば
      c->n[i]=e.n[i]-f.n[i];//ci=ai-bi 
      h=0;//h=0
    }
    if(e.n[i] < f.n[i]){//ai<biならば
      c->n[i]=10+e.n[i]-f.n[i];//ci=10+ai-bi
      h=1;//h=1
    }      
  }

  if(h != 0){
    printf("/erroe\n");
    return -1;
  }

    
  return 0; 

}
コード例 #4
0
ファイル: enshu5.c プロジェクト: mimter/Integer
int multiple(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c)
{
	int i,j,h=0,tempb,tempa,e;
	struct NUMBER d,mai1,mai2,temp;
	clearByZero(&d);
	clearByZero(c);
	if(getSign(a)==1)
	{
		if(getSign(b)==1)
		{
			for(i=0;i<KETA-1;i++)
			{
				h=0;
				clearByZero(&d);
				
				tempb=b->n[i];
				for(j=0;j<KETA;j++)
				{
					tempa=a->n[j];
					e=tempa*tempb + h;
					if(j+i<KETA)
						d.n[j+i]=e%10;
					h=e/10;
				}
				copyNumber(c,&temp);
				add(&temp,&d,c);
			}
		}
		else if(getSign(b)==-1)
		{
			getAbs(b,&mai1);
			multiple(a,&mai1,c);
			setSign(c,-1);
		}
	}
	else if(getSign(a)==-1)
	{
		if(getSign(b)==1)
		{
			getAbs(a,&mai1);
			multiple(b,&mai1,c);
			setSign(c,-1);
		}
		else if(getSign(b)==-1)
		{
			getAbs(a,&mai1);
			getAbs(b,&mai2);
			multiple(&mai1,&mai2,c);
		}
	}
}
コード例 #5
0
ファイル: enshu5.c プロジェクト: mimter/Integer
int add(struct NUMBER *a,struct NUMBER *b, struct NUMBER *c)
{
	int i,e=0,d=0;
	int flag=0;
	struct NUMBER temp,temp2;
	clearByZero(&temp);
	clearByZero(&temp2);
	clearByZero(c);

	if(getSign(a)==1)
	{
		if(getSign(b)==1)
		{
			for(i=0;i<KETA;i++)
			{
				d=a->n[i]+b->n[i]+e;
				if(i==KETA-1 && d>=10)
				{
					printf("OverFlow\n");
					clearByZero(c);
					flag=1;
					break;
				}
				c->n[i]=d%10;
				e=d/10;	
			}
		}
		else if(getSign(b)==-1)
		{
			getAbs(b,&temp);
			sub(a,&temp,c);
		}
	}
	else
	{
		if(getSign(b)==1){
			getAbs(a,&temp);
			sub(b,&temp,c);
		}
		else if(getSign(b)==-1)
		{
			getAbs(a,&temp);
			getAbs(b,&temp2);
			add(&temp,&temp2,c);
			setSign(c,-1);
		}
	}

	return flag;
}
コード例 #6
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//多倍長変数の加算
int add(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c){

  int i;
  int D;
  int E=0;
  int cha,chb;
  int flag=0;
  struct NUMBER d,e;

  clearByZero(c);

  for(i=KETA-1;i>-1;i--){
    D=a->n[i]+b->n[i]+E;
    c->n[i]=D%10;
    E=D/10;
  }

  if(E != 0){
    printf("/erroe\n");
    return -1;
  }

  return 0;

}
コード例 #7
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
int sub(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c)
{
	int i,f_hizero = 0,h = 0,res = 0,tmp = 1;

	struct NUMBER tmp_a,tmp_b;

	/*値を動かすので一時的に保存*/
	copyNumber(a,&tmp_a);
	copyNumber(b,&tmp_b);

	if(numComp(a,b) == -1)
	{
		copyNumber(a,&tmp_b);
		copyNumber(b,&tmp_a);//a > bにしたいので
		tmp = -1;
	}
	else
	{
		copyNumber(a,&tmp_a);
		copyNumber(b,&tmp_b);
	}

	clearByZero(c);//cを0に

	if(getSign(a) == 1&&getSign(b) == 1)//a,bも+の時は通常のsub
	{
		if(numComp(&tmp_a,&tmp_b) == 0)
			return(0);//aとbが同じならcは0だから
		f_hizero = firstNotZero(&tmp_a);//aは必ず大きい値なのでf_hizeroも大きい方になる
		/*計算部*/
		for(i = 0;i <= f_hizero;i++)
		{
			tmp_a.n[i] -= h;//繰り下がり分を引く
			h = (tmp_a.n[i]>=tmp_b.n[i])? 0:1;
			c->n[i] = h * 10 + tmp_a.n[i] - tmp_b.n[i];
		}

		if(f_hizero == KETA - 1&&h != 0)
			res = -1;

		setSign(c,tmp);
	}

	/*絶対値を使うので保存*/
	getAbs(a,&tmp_a);
	getAbs(b,&tmp_b);

	if(getSign(a) == 1 && getSign(b) == -1)//aが+、bが-の時はa+b通常のadd
		res = add(a,&tmp_b,c);
	if(getSign(a) == -1 && getSign(b) == 1 )//aが-、bが+の時は-a-b、つまり-(a+b)、addの結果を負にする
	{
		res = add(b,&tmp_a,c);
		setSign(c,-1);
	}
	if(getSign(a) == -1 && getSign(b) == -1)//aもbも-の時は-a + b、つまりb-aをすればいい。
		res = sub(&tmp_b,&tmp_a,c);

	return(res);
}
コード例 #8
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
void copyNumber(struct NUMBER *a,struct NUMBER *b)
{
	int i;
	clearByZero(b);//一応0クリア
	for(i = 0;i < KETA;i++)//最大桁までiを大きくする
		b->n[i] = a->n[i];
	setSign(b,getSign(a));
}
コード例 #9
0
ファイル: enshu5.c プロジェクト: mimter/Integer
int divBy10(struct NUMBER *a,struct NUMBER *b)
{
	int i,flag=0;
	flag=a->n[0];
	clearByZero(b);

	for(i=0;i<KETA-1;i++)
		b->n[i]=a->n[i+1];
	return flag;

}
コード例 #10
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
int divBy10(struct NUMBER *a,struct NUMBER *b)
{
	int i,f_hizero = firstNotZero(a),res = 0;

	clearByZero(b);//0で初期化する

	res = a->n[0];//最下位桁の値がそのままあまりになるので
	for(i = 0;i < f_hizero;i++)//bにi + 1が含まれるのを考慮してi = 1
		b->n[i] = a->n[i + 1];//a[i + 1]の値を変更するのでf_hizero未満でiを動かす
	setSign(b,getSign(a));//aとbの符号をそろえる
	return(res);
}
コード例 #11
0
ファイル: enshu5.c プロジェクト: mimter/Integer
int mulBy10(struct NUMBER *a,struct NUMBER*b)
{
	int i,flag=0;
	clearByZero(b);
	if(a->n[KETA-1]!=0)
		flag=-1;
	else
		for(i=KETA-1;i>0;i--)
		{
			b->n[i]=a->n[i-1];
		}

	return flag;
}
コード例 #12
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//int型変数のセット
void setInt(struct NUMBER *a,int x){

  int amari;
  int i;

  clearByZero(a);

  for(i=KETA-1;i>0;i--){
    amari=x%10;
    a->n[i]=amari;
    x=(x-amari)/10;
  }

}
コード例 #13
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
int mulBy10(struct NUMBER *a,struct NUMBER *b)
{
	int i,f_hizero = firstNotZero(a),res = 0;

	clearByZero(b);//0で初期化する

	if(f_hizero == KETA - 1)//最初の非ゼロが最高桁なら
		res = -1;//フローがある
	else if(f_hizero == 0)//最初の非ゼロが最低桁(0)なら
		res = -1;//十倍しても意味がない(アンダーフロー…?)

	for(i = 0;i <= f_hizero;i++)//最高位の非ゼロまで
		b->n[i + 1] = a->n[i];//a[i]をb[i + 1]にうつす = 10倍
	setSign(b,getSign(a));//aとbの符号をそろえる
	return(res);
}
コード例 #14
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
int arctan(struct NUMBER *a,struct NUMBER *b)
{
	struct NUMBER i,tmp1,tmp2;
	struct NUMBER apow,tenpow,mone,n;//計算に使う変数
	int j,res;

	clearByZero(b);
	clearByZero(&i);
	clearByZero(&tmp1);
	clearByZero(&tmp2);
	clearByZero(&apow);
	clearByZero(&tenpow);
	setInt(&n,1);

	tenpow.n[KETA-1] = 1;//tenpowは10^(KETA-1)
	j = 0;
	while(1)
	{
		res = fastpower(a,&n,&apow);//apow = a^n
		if(res != 0)
			break;

		res = multiple(&n,&apow,&tmp1);//tmp1 = n * apow
		if(res != 0)
			break;
		res = divide(&tenpow,&tmp1,&tmp2,&apow);//tmp2 = tenpow/tmp1,apowは使わないからこれ以降使わないから


		if(res != 0)
			break;
		if(i.n[0]%2)//iが奇数なら,手っ取り早く偶奇を見たいからこう
			setSign(&tmp2,-1);
		else //iが偶数なら
			setSign(&tmp2,1);
		copyNumber(b,&tmp1);

		add(&tmp1,&tmp2,b);//b += (1/n * 1/(a^n)) * 10^(KETA-1),オーバーフローなどはないので戻り値は保存しない
		if(firstNotZero(&tmp2) <= KETA/10)//(1/i * 1/(a^i)) * 10^(KETA-1)がKETAの1/10程度になったら
			break;

		/*2i +1の操作*/
		copyNumber(&i,&tmp1);//i → tmp 
		increment(&tmp1,&i);//i++
		copyNumber(&i,&tmp1);//i → tmp1
		add(&tmp1,&i,&n);//n = 2i(n= i + i)
		copyNumber(&n,&tmp1);//i → tmp 
		increment(&tmp1,&n);//i++
	}
	return(res);
}
コード例 #15
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//多倍長変数のコピー
void copyNumber(struct NUMBER *c,struct NUMBER *d){

  int i;
  int x;
  int ck;

  clearByZero(d);
  ck=readKETA(c);

  d->sign = c->sign;

  for(i=0;i<KETA-ck;i++){
    d->n[i]=0;
  }
  
  for(i=KETA-ck;i<KETA;i++){
    d->n[i]=c->n[i];
  }
  
}
コード例 #16
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
int add(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c)
{
	int d = 0,e = 0,f_hizero = 0,i,res = 0;

	struct NUMBER abs_a,abs_b;

	/*絶対値を使う可能性があるので保存*/
	getAbs(a,&abs_a);
	getAbs(b,&abs_b);

	clearByZero(c);
	f_hizero = (firstNotZero(a)>firstNotZero(b))?firstNotZero(a):firstNotZero(b);
											//f_hizeroは最初の非ゼロが現れる場所が高い方の非ゼロの場所を格納
	/*計算部*/
	if(getSign(a) == 1&&getSign(b) == 1)//a,bも+の時は通常のadd
	{
		for(i = 0;i <= f_hizero + 1&&i <= KETA - 1;i++)
							//桁上りがある場合があるのでf_hizero + 1まで、またf_hizero == KETA-1の時はKETA-1まで
		{
			d = a->n[i] + b->n[i] + e;
			c->n[i] = d%10;
			e = d / 10;
		}

		if(f_hizero == KETA - 1&&e != 0)
			res = -1;
	}

	if(getSign(a) == 1 && getSign(b) == -1)//aが+、bが-の時はa-b通常のsub
		res = sub(a,&abs_b,c);

	if(getSign(a) == -1 && getSign(b) == 1)//aが-、bが+の時は-a+b、つまりb-a、aとbが逆になったsub
		res = sub(b,&abs_a,c);

	if(getSign(a) == -1 && getSign(b) == -1)//aもbも-の時は-(a+b)、つまりaddの結果を負にする
	{
		res = add(&abs_a,&abs_b,c);
		setSign(c,-1);//cを-にする
	}
	return(res);
}
コード例 #17
0
ファイル: enshu5.c プロジェクト: mimter/Integer
int setInt(struct NUMBER *a,int x)
{
	int i;
	clearByZero(a);
	if(x<0)
	{
		setSign(a,-1);
		x=x*(-1);
	}
	else if(x>0)
		setSign(a,1);
	else
		setSign(a,0);

	for(i=0;i<KETA;i++)
	{
		a->n[i]=x%10;
		x=x/10;
		if(x<1)
			break;
	}
}
コード例 #18
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//ウォリス積の計算
//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;

}
コード例 #19
0
ファイル: clearByZero.c プロジェクト: beeeeeeeetm/sourcebox
//除算(ひっ算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;

}
コード例 #20
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
int multiple(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c)
{
	int e,h,res = 0,i,j,f_hizero_a,f_hizero_b;
	struct NUMBER d,tmp_c,abs_a,abs_b,tmp;
	clearByZero(c);
	clearByZero(&tmp_c);

	/*絶対値を使う場合があるので*/
	getAbs(a,&abs_a);
	getAbs(b,&abs_b);

	if(isZero(a) == 0 || isZero(b) == 0)
		return(0);//もうcは0になっているのでcBZはしない

	setInt(&tmp,1);//tmpに1を代入

	if(numComp(a,&tmp) == 0)//aとtmpが同じ値なら = aが1なら
	{
		copyNumber(b,c);//cにbをコピー
		return(0);
	}
	if(numComp(b,&tmp) == 0)
	{
		copyNumber(a,c);//cにaをコピー
		return(0);
	}

	f_hizero_a = firstNotZero(a);//aの最初の非ゼロを数える、これはjの最大値となる
	f_hizero_b = firstNotZero(b);//bの最初の非ゼロを数える、これはiの最大値となる

	if(getSign(a) == 1&&getSign(b) == 1)//a,bも+の時は通常のmultiple
	{
		for(i = 0;i <= f_hizero_b;i++)//第一ループ、求めるのはa * b
		{
			h = 0;
			clearByZero(&d);

			if(b->n[i] == 0)//a * bのbが0の時の結果は0
				clearByZero(&d);
			else if(b->n[i] == 1)//a * bのbが1の時の結果はa
			{
				for(j = 0;j <= f_hizero_a;j++)
				{
					d.n[j + i] = a->n[j];
				}
			}
			else
			{
				for(j = 0;j <= f_hizero_a;j++)//第二ループ、求めるのはa * b_i
				{
					if(i + j >KETA - 1)//i + jは値を代入する部分なのでここがKETA - 1を超えていたらアウト
						return(-1);
					e = a->n[j] * b->n[i] + h;//eにa_j * b_iと前の繰り上がりを足す
					d.n[j + i] =e % 10;//d_i+jにeの一桁目を代入
					h = e / 10;//hにeの二桁目を代入 = 繰り上がり
				}
			}
			
			if(i + j < KETA)
				d.n[j + i] = h;//jがf_hizero_aまでなので乗算した時のhをここに代入する。

			else if(h != 0)
				return(-1);

			res = add(c,&d,&tmp_c);

			if(res == -1)//addでオーバーフローが起きた時のためのif
				return(-1);	

			copyNumber(&tmp_c,c);
		}
	}
	if(getSign(a) == 1 && getSign(b) == -1)//aが+、bが-の時は-(a*|b|)
	{
		res = multiple(a,&abs_b,c);
		setSign(c,-1);
	}
	if(getSign(a) == -1 && getSign(b) == 1 )//aが-、bが+の時は-(|a|*b)
	{
		res = multiple(&abs_a,b,c);
		setSign(c,-1);
	}
	if(getSign(a) == -1 && getSign(b) == -1)//aもbも-の時は|a| * |b|
		res = multiple(&abs_b,&abs_a,c);
	return(res);
}
コード例 #21
0
ファイル: machin.c プロジェクト: sa2taka/alogorithm
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);
}