高精度乘法

2021-08-18 01:23:36 字數 2905 閱讀 5231

1.高精度乘法原理

高精度乘法問題主要利用了乘法原理,利用字元陣列存放超過數字型別長度的數,然後將字元陣列的值轉入數字陣列內進行計算。

該演算法的核心就是利用兩個迴圈依次迴圈處理各位數,然後判斷是否需要進製。

# include # include // 呼叫strlen函式的標頭檔案

#pragma warning(disable:4996)

int main(void) ; // 再定義三個陣列,前兩個用於存放字元陣列裡的數字各個位的數值,最後乙個用於儲存最終結果的各個位的數值

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++) // 此處第

一、第二個式子用+=,原因可根據乘法原理解釋,第三個式子無需+=,原因是取該位數總值的個位即可

if (c[len - 1] == 0) // 此處是判斷輸出的第乙個數字是否為0,若為0,忽略該位數,即總長減去1

len--;

for (int i = len - 1; i >= 0; i--) // 倒著輸出陣列內的數字,得到最終結果

printf("%d", c[i]);

return 0;

}

下面是乙個高精度的例子

眾所周知,2的正整數次冪最後一位數總是不斷的在重複2,4,8,6,2,4,8,6……我們說2的正整數次冪最後一位的迴圈長度是4(實際上4的倍數都可以說是迴圈長度,但我們只考慮最小的迴圈長度)。類似的,其餘的數字的正整數次冪最後一位數也有類似的迴圈現象: 迴圈

迴圈長度 2

2、4、8、6 4

33、9、7、1 4

44、6 2

5 51 6

6 17

7、9、3、1 4

88、4、2、6 4

99、1 2

這時樂樂的問題就出來了:是不是只有最後一位才有這樣的迴圈呢?對於乙個整數n的正整數次冪來說,它的後k位是否會發生迴圈?如果迴圈的話,迴圈長度是多少呢?

注意:1. 如果n的某個正整數次冪的位數不足k,那麼不足的高位看做是0。

2. 如果迴圈長度是l,那麼說明對於任意的正整數a,n的a次冪和a + l次冪的最後k位都相同。

#include#include#include#include#includeusing namespace std;

string s;

int m, k; int i, j; int a[205], aans[205], n[205], ans[205], last[205], now[205], t[205];

int single_j[12] = ;//單迴圈結

void init() //將m存入陣列n,以便於高精度

}void multiplyh(int x, int y, int z) }}

void multiplyl(int x, int yy, int z)

}int main()

//更新為第一次出現末尾迴圈節的狀態

}t[1] = single_j[n[1]];//最低位的迴圈結

for (int i = 1; i <= k; i++) now[i] = ans[i];

int pos = 2;//當前倒數字數

while (pos <= k)

tmp = 0;

while (tmp < 11)

if (ans[pos] == n[pos]) break;//找到迴圈結

memset(aans, 0, sizeof(aans));

multiplyh(last, now, aans);//更新last

for (j = 1; j <= k; j++) last[j] = aans[j];

}if (tmp >= 11)

for (int j = 1; j <= k; j++) now[j] = last[j];

memset(aans, 0, sizeof aans);

multiplyl(t, tmp, aans);//更新迴圈節陣列

for (int i = 1; i <= 100; i++) t[i] = aans[i];

pos++;

}int flag = 0;//不輸出前導0

for (int i = 100; i >= 1; i--)

//cout << endl;

return 0;

}

高精度減法,高精度乘法

高精度減法 oj資料偏弱如果新增乙個101 2就錯了,下面這一步是為了防止錯誤的 if a aa 0 可能出現第一位的1被借走的的情況,所以加乙個while找第乙個不是0的 while c i 0 i include include include include include include u...

高精度乘法

問題描述 給你兩個正整數a,b,計算它們的乘積。輸入格式 第一行乙個正整數a 第二行乙個正整數b 輸出格式 一行,表示a b 樣例輸入 111222333444555666777888999 999888777666555444333222111 樣例輸出 提示 a,b分別不超過100000位 ff...

高精度乘法

include include include includeusing namespace std const int maxn 5000 inline int get struct data data operator const data b for int i 1 i c.len i whi...