一本通-高精度計算
阿新 • • 發佈:2021-03-11
1. 進位、借位處理
加法進位: 下標地位是個位,高位是十位、百位。輸出的時候倒著輸出。計算著時候必須先儲存個位
c[i] = a[i] + b[i];
if(c[i] >= 10){ //高位進位
c[i] %= 10;
c[i+1]++;
}
減法進位: a[i]-b[i]
if(a[i] < b[i]){
a[i+1]--; //高位借位
a[i] += 10;
}
c[i] = a[i] - b[i];
乘法進位: 看不懂,下面會解釋
e[i+j-1] = c[i] * d[j] + e[i+j-1]; //新計算的值+累計原位置的值 if(e[i+j-1] >= 10){ e[i+j] += e[i+j-1] / 10; // 進位 e[i+j-1] = e[i+j-1] % 10; }
2. 高精度加法
http://ybt.ssoier.cn:8088/problem_show.php?pid=1168
求兩個不超過200位的非負整數的和。
【輸入】
有兩行,每行是一個不超過200位的非負整數,可能有多餘的前導0。
【輸出】
一行,即相加後的結果。結果裡不能有多餘的前導0,即如果結果是342,那麼就不能輸出為0342。
【輸入樣例】
22222222222222222222
33333333333333333333
【輸出樣例】
55555555555555555555
#include <iostream> using namespace std; const int maxn = 205; char m[maxn],n[maxn]; int a[maxn],b[maxn],c[maxn]; int main(int argc, char const *argv[]){ cin >> m >> n; int lenA = strlen(m),lenB = strlen(n); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); //char陣列轉為int陣列,同時倒置,個位儲存下標低的, 為了計算方便 for(int i = 0; i < lenA; i++) a[lenA-i-1] = m[i] - '0'; for(int i = 0; i < lenB; i++) b[lenB-i-1] = n[i] - '0'; int maxLen = max(lenA,lenB); for(int i = 0; i < maxLen; i++){ c[i] += a[i] + b[i]; if(c[i] >= 10){ c[i] %= 10; c[i+1]++; } } //去除c的後置0 int p = maxn-1; while(c[p] == 0){ p--; } for(int i = p; i >= 0; i--) cout << c[i]; return 0; }
3. 高精度減法
http://ybt.ssoier.cn:8088/problem_show.php?pid=1169
【題目描述】
求兩個大的正整數相減的差。
【輸入】
共2行,第1行是被減數a,第2行是減數b(a > b)。每個大整數不超過200位,不會有多餘的前導零。
【輸出】
一行,即所求的差。
【輸入樣例】
9999999999999999999999999999999999999
9999999999999
【輸出樣例】
9999999999999999999999990000000000000
#include <iostream> using namespace std; const int maxn = 205; char a[maxn],b[maxn]; int c[maxn],d[maxn],e[maxn]; int main(int argc, char const *argv[]){ cin >> a >> b; int lenA = strlen(a),lenB = strlen(b); memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); for(int i = 0; i < lenA; i++) c[i] = a[lenA-i-1] - '0'; for(int i = 0; i < lenB; i++) d[i] = b[lenB-i-1] - '0'; for(int i = 0; i < lenA; i++){ e[i] += c[i] - d[i]; if(e[i] < 0){ e[i+1]--; e[i]+= 10; } } int p = maxn; while(e[p] == 0) p--; for(int i = p; i >= 0; i--){ cout << e[i]; } return 0; }
4. 高精度乘法
c[i] 與 a[i]*b[j]的乘積、進位、原來的c[i]有關
#include <iostream>
using namespace std;
const int maxn = 105;
char a[maxn],b[maxn];
int c[maxn],d[maxn],e[maxn*2];
int main(int argc, char const *argv[]){
cin >> a >> b;
int lenA = strlen(a),lenB = strlen(b);
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
for(int i = 0; i < lenA; i++) c[lenA-i] = a[i] - '0';
for(int i = 0; i < lenB; i++) d[lenB-i] = b[i] - '0';
// c[1]至c[lenA] d[1]至d[lenB] ,從低位至高位
for(int i = 1; i <= lenA; i++){
for(int j = 1; j <= lenB; j++){
e[i+j-1] = c[i] * d[j] + e[i+j-1]; //新計算的值+累計原位置的值
if(e[i+j-1] >= 10){
e[i+j] += e[i+j-1] / 10; // 進位
e[i+j-1] = e[i+j-1] % 10;
}
}
}
int p = maxn*2-1;
while(e[p] == 0) p--;
for(int i = p; i >= 1; i--) cout << e[i];
return 0;
}
5. 高精度除法
高精度除以低精度
做除法時,每一次的商的值都在0~9,每次求得的餘數連線以後的若干位得到的新的被除數,繼續做除法。因此,在做高精度除法時,要涉及到乘法運算和減法運算,還有移位處理。
當然為了程式簡潔,可以避免高精度乘法,用0~9次迴圈減法取代商的值。
這裡,我們討論一下高精度數除以當精度數的結果,採取的方法是按位相除法。