1.高精度加法
1.1 高精度加法
高精度運算的基本運算就是加和減。和算數的加減規則同樣, 模擬豎式計算,考慮錯位運算與進位處理。下面是我老師給的代碼,目前比網上其餘的代碼要精簡和巧妙。#include <cstdio> #include <cstring> int main() { char a[202]={0}, b[202]={0}; scanf("%s%s", a, b); int alen = strlen(a), blen = strlen(b), t = 0, i; int a1[202]={0}, b1[202]={0}; for (i = 0; i < alen; i++) a1[i] = a[alen-1-i]-'0'; for (i = 0; i < blen; i++) b1[i] = b[blen-1-i]-'0'; alen = (alen > blen) ? alen : blen; for (i = 0; i <= alen; i++) t = a1[i]+b1[i], a1[i] = t%10, a1[i+1] += t/10; while (!a1[i] && i) i--; for(; i >= 0; i--) printf("%d", a1[i]); return 0; }
1.2高精度加法(壓位)
int型能夠存9位數字,而上述代碼在數組的每一個元素中只存了0-9中的一位數,能夠說浪費了不少空間,並且計算機計算4+5和3333+4444用的時間是相同的,因此咱們有時候用壓位來節省空間和時間。其原理以下:
ios
- 從鍵盤讀入大整數並存放在字符數組中
- 從後向前每八位數字存放在一個int型數組的一個元素中
- 對倆個數組的對應元素進行加減運算,有進位要進位,最後輸出
如下是我老師給的代碼:數組
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int INF = 1E8; struct Data{ int u[50], l; Data(){ memset(u, 0, sizeof(u)), l = 0; } void change(string a){ int len = a.size(), k = len / 8, i = 0; l = k + (len%8 > 0); for (len; len > 8; len -= 8) sscanf(a.substr(len-8, 8).c_str(), "%d", &u[i++]);//註釋一 if (len > 0) sscanf(a.substr(0, len).c_str(), "%d", &u[i]); } void print(){ int k = l-1; printf("%d", u[k--]); while (k >= 0) printf("%8.8d", u[k--]);//註釋二 printf("\n"); } }a, b; int main(){ string aa, bb, ac; cin >> aa >> bb; int ka = 0, kb = 0, i; a.change(aa), b.change(bb); for (i = 0; i < 50; i++) a.u[i] += b.u[i], a.u[i+1] += a.u[i] / INF, a.u[i] %= INF; for (i = 49; a.u[i]==0 && i>0; i--); a.l = i + 1; a.print(); return 0; }
2.高精度減法
2.1 高精度減法
原理和加法同樣,須要不過考慮的不是進位,而是借位。
spa
代碼以下:code
#include <cstdio> #include <cstring> int main() { char a[202]={0}, b[202]={0}; scanf("%s%s", a, b); int alen = strlen(a), blen = strlen(b), t = 0, i; int a1[202]={0}, b1[202]={0}; for (i = 0; i < alen; i++) a1[i] = a[alen-1-i]-'0'; for (i = 0; i < blen; i++) b1[i] = b[blen-1-i]-'0'; alen = (alen > blen) ? alen : blen; for (i = 0; i <= alen; i++) t = a1[i]-b1[i], t<0?(t+=10,a1[i+1]--):t, a1[i] = t; while (!a1[i] && i) i--; for(; i >= 0; i--) printf("%d", a1[i]); return 0; }
2.2 高精度減法(壓位)
減法和加法大同小異,若是你會了加法,那麼減法也不足爲懼。如下代碼是我本身寫的,和我老師寫的有必定差距,若有不足請指出。ci
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int INF = 1E8; struct Data{ int u[50], l; Data(){ memset(u, 0, sizeof(u)), l = 0; } void change(string a){ int len = a.size(), k = len / 8, i = 0; l = k + (len%8 > 0); for (len; len > 8; len -= 8) sscanf(a.substr(len-8, 8).c_str(), "%d", &u[i++]); if (len > 0) sscanf(a.substr(0, len).c_str(), "%d", &u[i]); } void print(){ int k = l-1; printf("%d", u[k--]); while (k >= 0) printf("%8.8d", u[k--]); printf("\n"); } }a, b; int main(){ string aa, bb, ac; cin >> aa >> bb; int ka = 0, kb = 0, i,t; a.change(aa), b.change(bb); for (i = 0; i < 50; i++) t = a.u[i] - b.u[i],(t < 0)?(t+=INF,a.u[i+1]--):t,a.u[i] = t; for (i = 49; a.u[i]==0 && i>0; i--); a.l = i + 1; a.print(); return 0; }以上的倆個代碼都只能當且僅當a>=b時才能正常工做,望注意。
3.高精度乘法
3.1 高精度乘法
這個方法出自吳永輝老師。此代碼簡直讓我拍手叫絕。原理以下:string
3 2 1 0 ——>數組a、b的下標
io
3 4 5 6 i ——>數組a[]class
* 1 2 7 8 j ——>數組b[]stream
————————————原理
2 7 6 4 8
2 4 1 9 2
6 9 1 2
3 4 5 6
——————————————————
4 4 1 6 7 6 8 ——>數組c[]
6 5 4 3 2 1 0 i+j ——>數組c的下標
以上是倆個四位數相乘的豎式計算方法。能夠看出,數的右面對齊,從低位向高位計算,計算結束後將一列結果相加即爲答案。那麼把倆個數從右向左依次標記爲0、一、2...n,那麼每一列的結果就是第一個數的下標爲i的數與第二個數的下標爲j的數相乘的結果,其存放在第i+j列。最終結果是每一列相加,就是i+j這一列全部數相加。因此能夠用c[i+j] += a[i]*b[j]。
for(int i = 0;i < LA-1;i++) for(int j = 0;j < LB-1;j++) c[i+j] += a[i]*b[j]; for(int i = 0;i < LA+LB;i++) if(c[i] >= 10){ c[i+1] += c[i]/10; c[i] %= 10; }