1.引言
本文主要針對自己學習大數處理過程中的一些思路進行整理記錄,以備后忘。大數相減與大數相加相比,需要考慮借位問題。處理借位需要考慮二種情況,假設被減數為Sub1,減數為Sub2,這些都是以字符串形式存儲的大數。 則大致要考慮二種情況的借位:
1) Length of Sub1 is greater or equal to Length of Sub2: 此時需要考慮兩種借位:一種是Sub1大數大於Sub2大數,則Sub1最高位(Sub1首位置)無需再進一步借位,此種狀況比較好處理;另一種是Sub1大數小於Sub2大數,則Sub1最高位還需進一步借位,此種情況處理稍微復雜,在下面將展開討論.
2)Length of Sub1 is less than Length of Sub2: 此種情況即Sub1最高位還需進一步借位情況,我們在此假設Sub1長度不足Sub2長度的部分填充0,以
"123"(sub1) - "456789"(sub2)為例,如下簡圖所示,最終結果應該為"456666",還要加負號表示結果為負數。在此過程中還要引入一個基數作為調整,基數設定原理是以第一種情況所算出的最終值為參考,如下圖參考基數所述,其實只要理解相減過程,此步不難理解。
具體代碼如下:
#include <iostream> #include <string.h> using namespace std; const int N=1005; void Sub(char *p1,char *p2,int *p3) { int i,j,k=0; int bit=0,t=0; //bit:表示借位,1:表示需要借位,0:表示不需要借位。t:存儲中間計算的位相減值 int len1=strlen(p1); //被減數的長度 int len2=strlen(p2); //減數的長度 for(i=len1-1,j=len2-1;i>=0 && j>=0;--i,--j) //此為循環遍歷兩數,分別對位進行相減操作 { t=(p1[i]-'0')-(p2[j]-'0')-bit; //計算兩個位之間的差值,同時要考慮借位 if(t<0) //如果t小於0,表示需要借位,bit賦值為1,且最終相減結果需加10作為調整並存儲到p3數組中,自己用筆畫一下就好理解. { bit=1; //例:123-456,t相減實際值分別為-3(3-6-0(bit)),-4(2-5-1(bit)),-4(1-4-1(bit)),加10調整后為: // 7,6,6,由於最高位相減后還bit為1即還需借位, 因此還需調整,轉換為第一種情況,即用1000-667=333,且結果為負 p3[k++]=t+10; } else { bit=0; //相減為正,則無需調整,直接將t賦給p3對應位。 p3[k++]=t; } } while(i>=0) //strlen(p1)>strlen(p2) ,result is greater than zero { t=p1[i]-'0'-bit; if(t<0) { bit=1; p3[k++]=t+10; } else { bit=0; p3[k++]=t; } i--; } while(j>=0) //strlen(p1)<strlen(p2),result is less than zero { t=10-bit-(p2[j]-'0'); p3[k++]=t; j--; } if(bit==1) //對仍有進位的情況考慮,主要分兩種:一種是strlen(p1)<strlen(p2),另一種是p1-p2<0,這兩種情況bit為1 { p3[0]=10-p3[0]; for(i=1;i<k;++i) { p3[i]=10-p3[i]-bit; } } if(bit==1) cout<<"-"; for(i=k-1;i>=0;--i) cout<<p3[i]; cout<<endl; } int main() { char c1[N],c2[N]; int a[N]; int i,j; while(cin>>c1>>c2) { memset(a,0,sizeof(a)); Sub(c1,c2,a); } return 0; }
2. 總結:
整個過程都是自己通過在紙上把各種情況考慮后轉換成的代碼,對於自己來說也是個熟悉的過程,希望能對大家有所幫助。