入門篇:高精度乘法
阿新 • • 發佈:2019-01-10
高精度乘法
標籤:C語言 高精度乘法
–by 小威威
1.為什麼寫這篇文章
在本次實驗課作業中,出現了高精度乘法,而老師還沒有講到,所以需要靠我們自己自學。然而,在網上許多高精度是錯誤的,即放到編譯器中無法正常執行,百度百科的高精度演算法是個坑!!!同時,即使是正確的,也只是一大段程式碼扔出來,根本沒有詳細的解釋,很難看懂。故我寫這篇文章是為了幫助與我有共同需求的初學者入門高精度乘法。
也許我的演算法很渣,但足以入門,接下來就要靠你自己探索咯。
2.高精度乘法例項
# include <stdio.h>
# include <string.h> // 呼叫strlen函式的標頭檔案
int main(void) {
char a1[250], b1[250]; // 先定義兩個字元陣列,用於儲存兩個較多位數的乘數
int a[250], b[250], c[500] = {0}; // 再定義三個陣列,前兩個用於接收字元數組裡的數字各個位的數值,最後一個用於儲存最終結果的各個位的數值
int len1, len2, len; // 前兩個分別表示字元陣列a1,b1的實際長度,最後一個表示兩個字元陣列實際長度之和
scanf("%s%s", a1, b1); // 對兩個字元陣列進行賦值
len1 = strlen(a1); // 將字串a1的長度賦給len1,用於陣列的賦值
len2 = strlen(b1); // 將字串b1的長度賦給len2, 用於陣列的賦值
len = len1 + len2; // 將兩字串實際長度之和賦給len
for (int i = 0; i < len1; i++) // 用for迴圈,實現字元陣列a1內數字向陣列轉移
a[i] = a1[len1-1-i] - '0';
/* 不過,字元陣列內的數字與陣列內數字順序相反,這與乘法原理有關,根據ASCII,字元陣列內的數字要轉化成實際的數字,就要減去48,因為‘0’的ASCII碼恰好是48,所以將字元陣列元素-‘0’以實現轉化 */
for (int j = 0; j < len2; j++) // 用for迴圈,實現字元陣列b1內數字向陣列轉移
b[j] = b1[len1-1-j] - '0';
for (int i = 0; i < len1; i++) // 接下來這兩個巢狀的for迴圈便是高精度乘法的核心
for (int j = 0; j < len2; j++) { // 此處這短短三步需要結合乘法原理理解,用文字很難表達
c[i+j] += a[i]*b[j]; // 數字的其中一位與另一數字其中一位相乘,先不考慮進位情況
c[i+j+1] += (c[i+j]) / 10; // 除以10的作用便是判斷進多少(注意是c[i+j])
c[i+j] = c[i+j] % 10; // 進位結束以後該數位便只去各位,故將其取餘取餘數(注意是c[i+j])
} // 此處第一、第二個式子用+=,原因可根據乘法原理解釋,第三個式子無需+=,原因是取該位數總值的個位即可
if (c[len-1] == 0) // 此處是判斷輸出的第一個數位是否為0,若為0,忽略該位數,即總長減去1
len--;
for (int i = len-1; i >= 0; i--) // 倒著輸出陣列內的數字,得到最終結果
printf("%d", c[i]);
return 0;
}
在該演算法的核心部分,我可能講的不大詳細,這裡就做一點補充吧。
3.演算法核心補充
高精度乘法主要是根據乘法原理設計的。
乘法原理就是我們平時在紙上所用到的乘法運算:
如
25
* 25
————————
125
50
————————
625
按照該原理設計for迴圈,實現各位數的相乘,同時實現進位等操作。
以上內容皆為個人觀點,如果有問題歡迎大家提出來,我們一起探討。