資訊學奧賽系列教程:高精度除法
阿新 • • 發佈:2018-11-30
我們平時做除法時,採用立豎式的方法計算:
被除數從高位開始,和被除數對齊,諸位“試商”,“試商”後被除數減去“試商”的數的乘積,如下圖所示:
採用計算機做高精度除法時,模擬日常除法的步驟。但計算機不可能做“試商”,這時,我們可以採用減法來模擬
"試商"的過程。演算法的步驟如下:
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; }