最近,在網上看到一篇講大數相減的文章,講的思想是對的,但是代碼編寫不正確,就對其進行了改正。
參考文章鏈接:http://www.cnblogs.com/ballwql/archive/2013/04/20/3032090.html
大數相減與大數相加相比,需要考慮借位問題。處理借位需要考慮二種情況,假設被減數爲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 isless than Length of Sub2: 此種情況即Sub1最高位還需進一步借位情況,我們在此假設Sub1長度不足Sub2長度的部分填充0,以"123"(sub1) -"456789"(sub2)爲例,如下簡圖所示,最終結果應該爲"456666",還要加負號表示結果爲負數。在此過程中還要引入一個基數作爲調整,基數設定原理是以第一種情況所算出的最終值爲參考,如下圖參考基數所述,其實只要理解相減過程,此步不難理解。
/**
* 大數相減,但這兩個大數是正整數
* 暫時沒有考慮有負數的情況和其他非法輸入的情況
*
*/
#include <iostream>
#include <string.h>
using namespace std;
const int N=1002;
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); //減數的長度
bool isBeginning0 = true;
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;
}
}
//strlen(p1)>strlen(p2) ,result is greater than zero
while(i>=0)
{
t=p1[i]-'0'-bit;
if(t<0)
{
bit=1;
p3[k++]=t+10;
}
else
{
bit=0;
p3[k++]=t;
}
i--;
}
//strlen(p1)<strlen(p2),result is less than zero
while(j>=0)
{
t = 0 - (p2[j]-'0') - bit;
if(t<0)
{
bit = 1;
p3[k++] = t + 10;
}
else
{
bit = 0;
p3[k++] = t;
}
j--;
}
//對仍有進位的情況考慮,主要分兩種:
//一種是strlen(p1)==strlen(p2),但p1<p2
//另一種是strlen(p1)<strlen(p2),p1<p2
//這兩種情況都是bit爲1
//但要注意1點:從低位到高位求減法時,要從不爲0的位開始減
if(bit==1)
{
for(j = 0; j < k; ++j)
if(p3[j] != 0)
break;
p3[j]=10-p3[j];
for(i=j+1;i<k;++i)
{
p3[i]=10-p3[i]-bit;
}
}
if(bit==1)
cout<<"-";
//數字前面的0不輸出,如-09,輸出-9
for(i=k-1;i>=0;--i)
{
if(isBeginning0 && p3[i] != 0)
isBeginning0 = false;
if(!isBeginning0)
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;
}
運行結果: