計算兩個小的整形數相加的,用自帶的+運算符就可以很容易的解決,但是對於兩個很大的數來講是會溢出的。用+運算符就無法完成了,當然你可以重載+運算符。
其實對於兩個大整數相加,就是用到我們小學時學加法的方法-------豎式加法,一位一位的去相加,相加的和大於9只要進一位就OK了。
代碼如下:
#include <string.h> #include <stdio.h> const int N=100; char s1[N],s2[N]; //保存輸入的兩個大整數 int bign1[N],bign2[N]; //把大整數轉換成整數的形式 //把字符數字逆序轉換成整數數字, void char_num(char *s,int bin[]){ int len=strlen (s); for (int i=len-1,k=0;i>=0;i--) bin[k++]=s[i]-'0'; } //計算兩個大整數的和 void _fun (int bin1[],int bin2[]){ int i,j; for (i=0,j=0;i<N;i++,j++){ bin1[i] += bin2[j]; if (bin1[i] > 9){ bin1[i] %= 10; bin1[i+1]++; } } } void print (int bin[]){ bool flag=false; for (int i=N;i>=0;i--){ if (flag) printf ("%d",bin[i]); else if (bin[i]){ //輸出第一個非零的數。 printf ("%d",bin[i]); flag=true; } } putchar ('\n'); } ///只能計算兩個正的大整數相加 int main(){ while (scanf ("%s%s",s1,s2)!=EOF){ memset (bign1,0,sizeof (bign1)); memset (bign2,0,sizeof (bign2)); char_num (s1,bign1); char_num (s2,bign2); _fun (bign1,bign2); print (bign1); } return 0; }
現在考慮乘法,基本的思路都是一樣的。
現用usigned ans1[200]和usigned ans2[200]來保存兩個乘數,用reault[400]來存放兩個乘數的乘積。需說明一下,兩個200位的數相乘,其積最大為400位的數。計算的過程和小學時的列豎式乘法基本相同,只不過編程方便把進位的步驟放在後面同一進行而已。
相以835x49為例進行說明:
1步:835x9 。5x9的得到45個1,3x9得到27個10,8x9得到72個100.由於不處理進位,所以結果為:
位數 3 2 1 0
-----0 0 0 72 27 45
接下來算4x5,得到20個10;故上述結果變為:
位數 3 2 1 0
-----0 0 0 72 47 45
再算4x3,得到12個100;故上述結果為:
位數 3 2 1 0
-----0 0 0 84 47 45
最後算4x8,得到32個1000;故上述結果為:
位數 3 2 1 0
-----0 0 32 84 47 45
自此,乘法已經算完了 。接下來處理進位的問題。
把realut[0]留下5,把4加到reault[1],得到51,把1留下,把5加到reault[2],得89.........
最後得到:
位數 4 3 2 1 0
----0 4 0 9 1 5
總結一個規律:一個數的第 i 位和另一個數的第 j 位相乘,一定是要累加到結果的第 i+j 位。(i ,j都是從0開始自右往左數)
代碼如下:
#include <stdio.h> #include <string.h> const int N=200; int len1,len2; void char_num (char *s,unsigned bin[]){ int len=strlen (s); for (int i=len-1,k=0;i>=0;i--) bin[k++]=s[i]-'0'; } void _fun (unsigned bin1[],unsigned bin2[],unsigned ans[]){ for (int i=0;i<len1;i++){ for (int j=0;j<len2;j++) ans[i+j] += bin1[i]*bin2[j]; //兩個數的 i j 位相乘 累加到結果的 i+j 位。 } } void _carry (unsigned bin[]){ int len=2*N; for (int i=0;i<len;i++){ if (bin[i] > 9){ bin[i+1] += bin[i] / 10; bin[i] %= 10; } } } void print (unsigned bin[]){ bool flag=false; for (int i=N*2;i>=0;i--){ if (flag) printf ("%d",bin[i]); else if (bin[i]){ printf ("%d",bin[i]); flag=true; } } if (!flag) putchar ('0'); //和 0 相乘的情況。 putchar ('\n'); } int main (){ unsigned ans1[N],ans2[N],reault[2*N+10]; char s1[N],s2[N]; while (scanf("%s%s",s1,s2)!=EOF){ memset (ans1,0,sizeof (ans1)); memset (ans2,0,sizeof (ans2)); memset (reault,0,sizeof (reault)); len1=strlen (s1),len2=strlen (s2); char_num (s1,ans1); char_num (s2,ans2); _fun (ans1,ans2,reault); _carry (reault); print (reault); } return 0; }