大數運算之大數減法

大數減法運算原理

類似於大數加法,大數減法也是經歷三個步驟(以235-37爲例):

  1. 字符串倒序並存爲整數數組類型,則存爲532,73兩個數組;
  2. 倒敘後逐位相減,運算前先進行比較5<7,2借位爲15,15-7=8,同時532中的3借位減一,8存於differ[0]中;
    22和7,2<3,借位爲12,12-3=9,同時22中的第二個2借位變爲1,9存於differ[1]中;
    剩下借位後的1,存於differ[2]中。如果differ數組末尾存在多個0,需要除去
  3. differ數組倒序輸出

需要解決的關鍵問題

  1. 比較被減位和減位,不夠減的話借位
  2. 減法後高位可能有多餘的0,需要去除
  3. 保證最後的結果又一位爲0,其實這種情況就是結果相等,可以在相減之前發現
  4. 在進行sub(big_num a,big_num b)函數之前,保證輸入的a>b,通過修改結構體符號將“小數-大數”變爲“大數-小數”,sub()函數只可以進行大數-小數運算

代碼細節如下

#include<stdio.h>
#include<string.h>
struct big_num{
    int num[1001];
    int len;
    char sign;
    big_num(){//默認生成的構造函數
    memset(num,0,sizeof(num));
    len=0;
    sign='+';
    //初始化爲+號,如果出現如果是小數-大數,需要加上‘-’,將兩個數變爲大數-小數
    }
};
big_num str2num(char str[])
//將讀入的字符串倒序並轉化爲數字
{
    big_num temp;
    int len=strlen(str);
    for(int i=0;i<len;++i)
    {
        temp.num[i]=str[len-i-1]-'0';
        //此處將'0'轉換爲數字48也可,48爲0對應的asc碼
    }
    temp.len=len;
    return temp;
}
big_num sub(big_num a,big_num b)
{
    big_num c;
    c.len=a.len;
    //以最長的作爲界限,按輸入條件的篩選,a.len>=b.len
    for(int i=0;i<c.len;++i)
    {
        if(a.num[i]<b.num[i])
        {//減法之前先進行判斷大小,不足則借位
            a.num[i+1]--;
            a.num[i]+=10;
        }
        c.num[i]=a.num[i]-b.num[i];//存儲當前減法結果
    }
    while(c.num[c.len-1]==0)
    //輸出結果前面包含多個0,需要去除
    //在進行加法運算前已經去除了兩個數相等的情況,故不會出現結果爲0的情況
    {
        c.len--;
    }
    return c;
}
void print(big_num c)
{
    if(c.sign=='-')
        printf("-");
    for(int i=0;i<c.len;++i)
    {//將結果倒序輸出
        printf("%d",c.num[c.len-1-i]);
    }
}
int main()
{
    int t=0;
    printf("請輸入需要計算的輪數:");
    scanf("%d",&t);//計算的輪數
    int flag=1;
    while(t--)
    {
        //讀入需要計算的字符串
        char num_a[1001],num_b[1001];
        scanf("%s",num_a);
        scanf("%s",num_b);

        //將讀入字符串轉化爲數字格式
        big_num re_a,re_b,differ;
        re_a=str2num(num_a);
        re_b=str2num(num_b);

        if(re_a.len>re_b.len)//a>b
        {
            differ=sub(re_a,re_b);
        }
        else if(re_a.len<re_b.len)//a<b
        {
            differ=sub(re_b,re_a);
            differ.sign='-';
        }
        else if(re_a.len==re_b.len)//a和b的長度相等
        {
            for(int i=re_a.len-1;i>=0;i--)
            {
                if(re_a.num[i]==re_b.num[i])
                {
                    if(i==0)//如果a=b
                    {
                        differ.num[0]=0;
                        differ.len=1;
                    }
                    continue;
                }
                else if(re_a.num[i]>re_b.num[i])
                {
                    differ=sub(re_a,re_b);
                    break;
                }
                else
                {
                    differ=sub(re_b,re_a);
                    differ.sign='-';
                    break;
                }
            }
        }
        printf("Case: %d \n",flag++);
        printf("%s - %s =",num_a,num_b);
        print(differ);
        printf("\n");
        if(t)printf("\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章