1. 程式人生 > >資訊學奧賽系列教程:高精度除法

資訊學奧賽系列教程:高精度除法

我們平時做除法時,採用立豎式的方法計算:

被除數從高位開始,和被除數對齊,諸位“試商”,“試商”後被除數減去“試商”的數的乘積,如下圖所示:

採用計算機做高精度除法時,模擬日常除法的步驟。但計算機不可能做“試商”,這時,我們可以採用減法來模擬

"試商"的過程。演算法的步驟如下:

1、將除數移動和被除數對齊,位數不夠時,補0,

2、利用被除數減去除數,一直減到被除數小於除數,減的次數,就是“試商”的結果,每移動一次。

3、重複上述步驟,一直到被除數和除數的位數相等為止。

高精度演算法的程式碼如下:

#include <iostream>
#include <cstring>
using namespace std;
const int N =1001;
int aa[N],bb[N],cc[N]; //定義計算數和輸出結果

void inputNum(string ss,int a[]); //輸入需要計算的數儲存到陣列
void printArr(int a[]);  //輸出陣列的元素
void jian(int a[],int b[]);
void jisuan(int a[],int b[],int c[]);
void movei(int a[],int b[],int i);

int compare (int a[],int b[]); //比較兩個高精度數大小

int main()
{
	string s1 ="525353422";
	string s2 ="253532";
	inputNum(s1,aa);
	printArr(aa);
	
	inputNum(s2,bb);
	printArr(bb);
	
	if (compare(aa,bb) ==0) cout<<1<<endl;
	else if (compare(aa,bb))
	{
		jisuan(aa,bb,cc);
	}
	else if (compare(aa,bb)<0)
	{
		jisuan(bb,aa,cc);
	}
	
	printArr(cc);
	printArr(aa);
	return 0;
}
int compare (int a[],int b[])
{
	int i;
	if (a[0]>b[0]) return 1;
	if (a[0]<b[0]) return -1;
	for (i=a[0];i>0;i--)
	{
		if (a[i]>b[i]) return 1;
	    if (a[i]<b[i]) return -1;
	}
	return 0;
}

void movei(int a[],int b[],int j)
{
	for (int i=1;i<=a[0];i++)
	{
		b[i+j-1] =a[i];
	}
	b[0] = a[0]+j-1;
}

void jisuan(int a[],int b[],int c[])
{
  c[0] = a[0]-b[0]+1; //上的位數 
  int temp[1001]; //臨時陣列,用於對除數進行移動
  for (int i=c[0];i>0;i--) 
  {
	  memset(temp,0,sizeof(temp)); //全置為0
	  movei(b,temp,i);  //高位對齊
  	  while (compare(a,temp)>=0)
      {
      	c[i]++; //每次加1
	    jian(a,temp);
      }
  }
  int m=c[0];
  while (c[0]>0 && c[m]==0) //處理商的位數
  {
	 c[0]--;
  }
    
}


void jian(int a[],int b[])
{
	for (int i=1;i<=a[0];i++)
	{
		if (a[i]<b[i])
		{
			a[i+1]--;
			a[i]+=10;
		}
		a[i]-=b[i];
	}
	int i=a[0];
	while (a[i]==0)
	{
		i--;
	}
	a[0]=i;
}

void inputNum(string ss,int a[])
{
	int len = ss.length();
	a[0] = len;
	for (int i=0;i<len;i++)
	{
		a[len-i] = ss[i] -48;//字元變成數字,並且倒序儲存
	}
}
void printArr(int a[])
{

	for (int i=a[0];i>0;i--)
	{
		cout<<a[i];
	}
	cout<<endl;
}