1. 程式人生 > 其它 >20192423 2021-2022-2 《網路與系統攻防技術》實驗七實驗報告

20192423 2021-2022-2 《網路與系統攻防技術》實驗七實驗報告

高精度

題目要求:

a) 涉及知識點:陣列、流程控制、函式等

b) 要求:用整型陣列表示10進位制大整數(超過2^32的整數),陣列的每個元素儲存大整數的一位數字,實現大整數的加減法。

實現細節:

  1. 完全模擬簡單計算過程:讀入資料,儲存資料,處理資料,輸出資料

    儲存 讀入

    這裡,根據題目要求,要用整數陣列來儲存,但是介於整數陣列讀入困難的問題,應該使用字串來處理輸入,然後再對字串就行處理輸入到整數陣列中,讀入字串時,數字最高位在字串首(下標小的位置)。但是習慣上,下標最小的位置存放的是數字的 最低位,即儲存反轉的字串。例下圖輸入15604121072時,先儲存進char陣列中,採用字串讀取,然後反轉處理成整數儲存在整數陣列中。

    程式碼實現:

    
    void read(int a[]) {
      static char s[LEN + 1];	//靜態
      scanf("%s", s);
    
      clear(a);
    
      int len = strlen(s);
      // 反轉
      for (int i = 0; i < len; ++i) a[len - i - 1] = s[i] - '0';
      // 字元轉數字
    }
    

    輸出

    從後向前找不為零的數,然後按位依次輸出即可

    void print(int a[]) {
      int i;
      for (i=LEN-1;i>=1;--i)              //這裡判定不能限定為i>=0;這樣的話執行完i=-1,會導致無輸出
        if (a[i] != 0) break;
      for (; i>=0;--i) 
        putchar(a[i] + '0');
      putchar('\n');
    }
    

    加法:

    按照豎式加法,從最低位開始,將兩個加數對應位置上的數值相加,並判斷是否達到或超過10 。如果達到,那麼處理進位:將更高一位的結果上增加 1,當前位的結果減少10 。(可以考慮取模,和除法,但是不可能出現大於18的情況,所以沒必要)

    本題所設定的最大位數為LEN=1000位,但一般令陣列的最大長度 LEN 比可能的輸入大一些, 然後略去末尾的幾次迴圈,可以省去不少邊界情況的處理,故在此迴圈到 LEN - 1 = 1003 已經足夠

    程式碼:

    void add(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i = 0; i < LEN - 1; ++i) {
        c[i]+=a[i]+b[i];    // 將相應位上的數碼相加
        if (c[i] >= 10) {
          c[i + 1]+=1;
          c[i]-=10;
        }
      }
    }
    

    減法:

    判定:先判定前面是否大於後面,如果不大於就換位,同時在前面加負號,

    首先判斷位數,位數大的大,然後相等時從最高位向低位判斷,如果對應位後大於前,說明傳入的第一個數比第二個數小,直接結束.

    int judge(int a[],int b[]){
      int i,j,k;
      //分別最大位
      for(i=LEN-1; i>=0;--i)
        if(a[i]!=0) 
          break;
      
      for(j=LEN-1; j>=0; --j)
        if(b[j] != 0)   break;
      //分別判斷
      if(i < j)   
        return 0;
      else if(i>j) 
        return 1;
      for(; i>= 0;--i){
        if(a[i]<b[i]) return 0;
      }
      return 1;
    }
    

    實現:從個位起逐位相減,遇到負的情況則向上一位借 1。

    void sub(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i=0; i<LEN-1; ++i) {
        c[i]+=a[i] - b[i];    // 逐位相減
        if (c[i]< 0) {
          c[i+1]-=1;
          c[i]+=10;
        }
      }
    }
    

    實現程式:

    #include<bits/stdc++.h>
    static const int LEN = 1004;
    
    int a[LEN], b[LEN], c[LEN];
    
    void clear(int a[]) {
      for (int i=0; i<LEN; ++i) 
        a[i] = 0;
    }
    
    void read(int a[]) {
      static char s[LEN + 1];     //靜態
      scanf("%s", s);
    
      clear(a);
    
      int len = strlen(s);
       // 反轉
      for (int i=0; i<len; ++i) 
        a[len - i - 1] = s[i] - '0';      // s[i] - '0' 就是 s[i] 所表示的數值
    }
    
    void print(int a[]) {
      int i;
      for (i=LEN-1;i>=1;--i)              //這裡判定不能限定為i>=0;這樣的話執行完i=-1,會導致無輸出
        if (a[i] != 0) break;
      for (; i>=0;--i) 
        putchar(a[i] + '0');
      putchar('\n');
    }
    int judge(int a[],int b[]){
      int i,j,k;
      //分別最大位
      for(i=LEN-1; i>=0;--i)
        if(a[i]!=0) 
          break;
      
      for(j=LEN-1; j>=0; --j)
        if(b[j] != 0)   break;
      //分別判斷
      if(i < j)   
        return 0;
      else if(i>j) 
        return 1;
      for(; i>= 0;--i){
        if(a[i]<b[i]) return 0;
      }
      return 1;
    }
    void add(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i = 0; i < LEN - 1; ++i) {
        c[i]+=a[i]+b[i];    // 將相應位上的數碼相加
        if (c[i] >= 10) {
          c[i + 1]+=1;
          c[i]-=10;
        }
      }
    }
    void sub(int a[], int b[], int c[]) {
      clear(c);
    
      for (int i=0;i<LEN-1;++i) {
        c[i]+=a[i]-b[i];    // 逐位相減
        if (c[i]<0) {
          c[i+1]-=1;
          c[i]+=10;
        }
      }
    }
    int main() {
      printf("Please make sure the first num is larger than the second.\nAnd make sure the maximum number of digits is 1000 \n");
      read(a);  read(b);
    
      printf(" the result of add is: ");
      add(a, b, c);
      print(c);
    
      printf(" the result of sub is: ");
      if(judge(a,b)) sub(a,b,c);
      else {  putchar('-'); sub(b,a,c);}
      
      print(c);
      return 0;
    }
    
    

    d單精度乘法

    實現時注意得兩個for迴圈分別判斷,要不然前面進位會對結果產生影響導致錯誤

    void mul(int a[],int e){
        for(int j=0;j<MAX;j++)
            b[j] *=e;
        for(int j=0;j<MAX;j++)
            if(b[j]>9){
                b[j+1]+=b[j]/10;
                b[j]%=10;
            }
        
    }