[C++]高精度演算法
阿新 • • 發佈:2018-11-25
目錄
高精度加法
用程式來模擬豎式加法即可,注意在輸出的時候除去多餘的前導零。
程式程式碼
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAX_SIZE = 3333; inline void High_precision_Addition(int *a, int *b, int *c) { c[0] = 1; int x = 0; while (c[0] <= a[0] || c[0] <= b[0]) { c[c[0]] = a[c[0]] + b[c[0]] + x; x = c[c[0]] / 10; c[c[0]] %= 10; ++c[0]; }; c[c[0]] = x; while (c[c[0]] == 0 && c[0] > 1) --c[0]; }; int main(int argc, char *argv[]) { char str1[MAX_SIZE], str2[MAX_SIZE]; cin >> str1 >> str2; int a[MAX_SIZE], b[MAX_SIZE], c[MAX_SIZE]; memset(a, 0, sizeof a); memset(b, 0, sizeof b); memset(c, 0, sizeof c); a[0] = strlen(str1); b[0] = strlen(str2); for (int i = 0; i < a[0]; ++i) a[a[0] - i] = str1[i] - '0'; for (int i = 0; i < b[0]; ++i) b[b[0] - i] = str2[i] - '0'; High_precision_Addition(a, b, c); for (int i = c[0]; i >= 1; --i) printf("%d", c[i]); cout.put('\n'); //和 return 0; };
高精度減法
用程式來模擬豎式減法即可,與高精度加法類似,不過得考慮被減數與減數的大小關係還得考慮借位,所以程式碼相對於高精度加法更為複雜。
程式程式碼
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAX_SIZE = 3333; inline bool Is_swap(char *__x_, char *__y_) { char Mid_Element[MAX_SIZE]; if ((strlen(__x_) < strlen(__y_)) || (strlen(__x_) == strlen(__y_) && strcmp(__x_, __y_) < 0)) { strcpy(Mid_Element, __x_); strcpy(__x_, __y_); strcpy(__y_, Mid_Element); return true; }; return false; }; inline void High_precision_Subtraction(int *a, int *b, int *c) { c[0] = 1; while (c[0] <= a[0] || c[0] <= b[0]) { if (a[c[0]] < b[c[0]]) { a[c[0]] += 10; --a[c[0] + 1]; }; c[c[0]] = a[c[0]] - b[c[0]]; ++c[0]; }; while (c[c[0]] == 0 && c[0] > 1) --c[0]; }; int main(int argc, char *argv[]) { char str1[MAX_SIZE], str2[MAX_SIZE]; cin >> str1 >> str2; bool flag = Is_swap(str1, str2); int a[MAX_SIZE], b[MAX_SIZE], c[MAX_SIZE]; memset(a, 0, sizeof a); memset(b, 0, sizeof b); memset(c, 0, sizeof c); a[0] = strlen(str1); b[0] = strlen(str2); for (int i = 0; i < a[0]; ++i) a[a[0] - i] = str1[i] - '0'; for (int i = 0; i < b[0]; ++i) b[b[0] - i] = str2[i] - '0'; High_precision_Subtraction(a, b, c); if (flag == true) cout.put('-'); for (int i = c[0]; i >= 1; --i) printf("%d", c[i]); cout.put('\n'); //差 return 0; };
高精度乘法
用程式模擬豎式乘法即可,在做乘法運算時,同樣也有進位,同時對每一位進行乘法運算時,必須進行錯位相加。
程式程式碼
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAX_SIZE = 3333; inline void High_precision_Multiplication(int *a, int *b, int *c) { int x; for (int i = 1; i <= a[0]; ++i) { x = 0; for (int j = 1; j <= b[0]; ++j) { c[i + j - 1] = a[i] * b[j] + x + c[i + j - 1]; x = c[i + j - 1] / 10; c[i + j - 1] %= 10; }; c[i + b[0]] = x; }; c[0] = a[0] + b[0]; while (c[c[0]] == 0 && c[0] > 1) --c[0]; }; int main(int argc, char *argv[]) { char str1[MAX_SIZE], str2[MAX_SIZE]; cin >> str1 >> str2; int a[MAX_SIZE], b[MAX_SIZE], c[MAX_SIZE]; memset(a, 0, sizeof a); memset(b, 0, sizeof b); memset(c, 0, sizeof c); a[0] = strlen(str1); b[0] = strlen(str2); for (int i = 0; i < a[0]; ++i) a[a[0] - i] = str1[i] - '0'; for (int i = 0; i < b[0]; ++i) b[b[0] - i] = str2[i] - '0'; High_precision_Multiplication(a, b, c); for (int i = c[0]; i >= 1; --i) cout << c[i]; cout.put('\n'); //積 return 0; };
高精度除法
高精度除法一般有高精度除以低精度與高精度除以高精度,前者程式碼較為簡單,後者則作用範圍更加廣闊。高精度除以低精度與前三種高精度演算法類似,都是按位運算;而高精度除以高精度則是以減法來模擬除法。
程式程式碼1
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX_SIZE = 3333;
inline int High_precision_Division(int *a, int b, int *c) {
int x;
for (int i = 1; i <= a[0]; ++i) {
c[i] = (x * 10 + a[i]) / b;
x = (x * 10 + a[i]) % b;
};
c[0] = 1;
while (c[c[0]] == 0 && c[0] < a[0]) ++c[0];
return x;
};
int main(int argc, char *argv[]) {
char str[MAX_SIZE]; int b;
cin >> str >> b;
int a[MAX_SIZE], c[MAX_SIZE];
memset(a, 0, sizeof a); memset(c, 0, sizeof c);
a[0] = strlen(str);
for (int i = 0; i < a[0]; ++i) a[i + 1] = str[i] - '0';
int x = High_precision_Division(a, b, c);
for (int i = c[0]; i <= a[0]; ++i) cout << c[i]; cout.put('\n'); //商
cout << x << endl; //餘數
return 0;
};
程式程式碼2
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
using namespace std;
const int MAX_SIZE = 3333;
inline void Input(int *radix) {
string str; cin >> str; radix[0] = str.length();
for (int i = 0; i < radix[0]; ++i) radix[radix[0] - i] = str[i] - '0';
};
inline void Print(const int *radix) {
if (radix[0] == 0) {cout << 0 << endl; return;};
for (int i = radix[0]; i >= 1; --i) printf("%d", radix[i]);
cout.put('\n'); return;
};
inline int Compare(const int *__x_, const int *__y_) {
if (__x_[0] > __y_[0]) return 1;
if (__x_[0] < __y_[0]) return -1;
for (int i = __x_[0]; i >= 1; --i) {
if (__x_[i] == __y_[i]) continue;
else if (__x_[i] > __y_[i]) return 1;
else if (__x_[i] < __y_[i]) return -1;
};
return 0;
};
inline void Subtraction(int *__x_, int *__y_) {
int sign = Compare(__x_, __y_);
if (sign == 0) {__x_[0] = 0; return;};
if (sign == 1) {
for (int i = 1; i <= __x_[0]; ++i) {
if (__x_[i] < __y_[i]) {
__x_[i] += 10; --__x_[i + 1];
};
__x_[i] -= __y_[i];
};
while (__x_[__x_[0]] == 0 && __x_[0] > 0) --__x_[0]; return;
};
};
inline void Numcpy(const int *radix, int *pending, int pos) {
for (int i = 1; i <= radix[0]; ++i) pending[i + pos - 1] = radix[i];
pending[0] = radix[0] + pos - 1;
};
inline void High_precision_Division(int *a, int *b, int *c) {
int sign = Compare(a, b);
if (sign == -1) {c[0] = 1; c[1] = 0; return;};
if (sign == 1 || sign == 0) {
int Temp[MAX_SIZE]; c[0] = a[0] - b[0] + 1;
for (int i = c[0]; i >= 1; --i) {
memset(Temp, 0, sizeof Temp); Numcpy(b, Temp, i);
while (Compare(a, Temp) != -1) {++c[i]; Subtraction(a, Temp);};
};
while (c[c[0]] == 0 && c[0] > 0) --c[0]; return;
};
};
int main(int argc, char *argv[]) {
int a[MAX_SIZE], b[MAX_SIZE], c[MAX_SIZE];
memset(a, 0, sizeof a); memset(b, 0, sizeof b); memset(c, 0, sizeof c);
Input(a); Input(b); High_precision_Division(a, b, c);
Print(c); Print(a); //商與餘數
return 0;
};
高精度階乘
高精度階乘的本質是什麼?實際上就是一個高精度乘法,所以code就很好寫了呀~不過還得做一個小優化來應付幾千甚至幾萬的階乘,要不然按位算的話就妥妥的TLE了呀。
程式程式碼
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX_SIZE = 3333;
inline void High_precision_Factorial(const int N, int *c) {
c[1] = 1; int x, temp, index = 2;
for (int i = 2; i <= N; ++i) {
x = 0;
for (int j = 1; j <= index - 1; ++j) { //小優化
temp = c[j] * i + x;
c[j] = temp % 10;
x = temp / 10;
};
while (x != 0) {
c[index++] = x % 10;
x /= 10;
};
};
for (int i = MAX_SIZE; i >= 1; --i) if (c[i] != 0) {c[0] = i; break;};
};
int main(int argc, char *argv[]) {
int N; cin >> N;
int c[MAX_SIZE]; memset(c, 0, sizeof c);
High_precision_Factorial(N, c);
for (int i = c[0]; i >= 1; --i) printf("%d", c[i]); cout.put('\n');
return 0;
};