大數的運算思想

    一、數字儲存的實現

           大數計算的因數和結果精度一般是少則數十位,多則幾萬位。在C/C++語言中定義的類型中精度最多隻有二十多位,因而我們採取用鏈表存貯的方式來存放大數。在計算中會用到從高位開始計算,和從低位開始計算數值的兩種情況。所以我們將鏈表定義爲雙向鏈表,其中爲一個單元來存貯數據,一個指針指向前方的數據,另一個指向後的數據。其結構爲:

struct Node  // 定義一個雙向鏈表用來存貯結果
{     char data;    // 數據*定義爲字符的原因:要顯示負號
     Node *next;   // 尾指針
    Node *ahead;   // 首指針
};

  二、大數加法運算的實現

e.g

   處理中注意的問題:

          1、必須判斷出操作數A、B的長度,以位長的一個作爲循環基礎。

         2、最後一位(最高位)的運算中,若進位不爲0,則需增設多一個存儲結點。

  三、減法運算的實現

      算法也是從低位開始減。先要判斷減數和被減數那一個位數長,減數位數長是正常減;被減數位數長,則被減數減減數,最後還要加上負號;兩數位數長度相等時,最好比那一個數字大,否則負號處理會很繁瑣;處理每一項時要,如果前一位相減有借位,就先減去上一位的借位,無則不減,再去判斷是否能夠減開被減數,如果減不開,就要借位後再去減,同時置借位爲1,否則置借位爲0。


處理中注意的問題:

      1、如果被減數大於減數時,指針和相應循環長度控制變量也要做相應的修改 

      2、結果可能會出現前面是一堆0的情況,要處理好,如當減數爲112,而被減數爲111時,會出現001 

四、乘法運算的實現

              首先說一下乘法計算的算法,從低位向高位乘,在豎式計算中,我們是將乘數第一位與被乘數的每一位相乘,記錄結果,之後,用第二位相乘,記錄結果並且左移一位,  以此類推,直到計算完最後一位,再將各項結果相加。得出最後結果。當然我們可以直接用這種方法,但要用多個鏈表來保存計算出的分結果, 之後結果再相加得到最後結果,但是這樣會浪費很多空間。

              只用一個鏈表來表示結果,先把第一位乘數與被乘數的結果保存在鏈表中,之後把存儲結果的頭部後移一位、也就是從鏈表的第二加起,當第二位乘數與被乘數結果加到第二之後的各個項內。以此類推,直到結束。這樣就可以用一個鏈表來存儲相乘後的結果。

  

處理中注意的問題:

      1、傳入和保存的都是字符,所以計算時要將字符轉化爲數字,算完再轉化爲字符存儲

       2、另外進位時要處理,當前的值加上進位的值再看本位數字是否又有進位;

      3、 輸出時要逆序輸出,因爲鏈表首指針是存的結果的最低位。函數爲了對應輸入輸出結果的一致性,都有采用了字符串輸出,所以在輸出時又將鏈表轉爲了字符串

五、除法運算的實現

               首先說一下我們所要的結果,當除數除不開被子除數時,不用除到小數,當除數小於被除數時,除數作爲餘數既可,不用再向下除了。

                 除法算法最容易想到的數字電路,或模擬電路時裏面有用門實現的除法器,做法是用除數減被除數,再用一個加法器去計算存儲結果,算法簡單明瞭,計算速度比算乘方時還慢,電路中計算的長度不過8位,16位,32位,而且都是硬件實現,現要算的是幾千位,幾萬位。特別是兩數位長度差很大時計算速度相當慢,如10000-3時要進行多少次鏈表運算啊。

            就是從高位向低位減,減時以被除數長度爲單位,從高位取出大於被除數的字符串,和被除數相減,減的次數爲結果,餘數從剩下的除數高位再取出幾位做補位,直到大於被除數。再減,循環減到被減數大於餘數加上補位,那麼這個新的餘數作爲結果返回。

 

 

處理中注意的問題:

   1/  除法算法計算時是用的最高位開始向低位減,所以要注意指針的位置。

    2/餘數和被減數相減時,一定要注意:一旦能夠減開被除數時,一定要每從除數那裏取一個字符時,結果也要對應補一個0。如111222/111

六、冪運算的實現

冪的實現是最爲簡單的了,國爲有了前面的算法做鋪墊,就是調用乘法函數,來循環去自乘,冪指數相應減1,直到冪指數變爲0時結束。




        

 




      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章