C++ 大數加、減、乘、除、乘方運算
阿新 • • 發佈:2019-01-14
#include <iostream> #include <string.h> #include <time.h> #define DIGIT 4 #define DEPTH 10000 #define MAX 100 #define MAXSIZE 200000 using namespace std; typedef int bignum_t[MAX + 1]; /* *Created by HarvestWu on 2018.06.28. */ //大數類 class BigInteger { public: int read(bignum_t a, istream& is );//輸入資料 void write(const bignum_t a, ostream& os );//輸出資料 int comp(const bignum_t a, const int c, const int d, const bignum_t b); void add(bignum_t a, const bignum_t b);//大數加法 void sub(bignum_t a, const bignum_t b);//大數減法 void sub(bignum_t a, const bignum_t b, const int c, const int d); void mul(bignum_t c, const bignum_t a, const bignum_t b);//大數乘法 void div(bignum_t c, bignum_t a, const bignum_t b);//大數除法 void pow(int b, int n);//大數乘方 private: }; //輸入資料 int BigInteger::read(bignum_t a, istream& is = cin) { char buf[MAX*DIGIT + 1], ch; int i, j; memset((void*)a, 0, sizeof(bignum_t)); if (!(is >> buf)) return 0; for (a[0] = strlen(buf), i = a[0] / 2 - 1; i >= 0; i--) ch = buf[i], buf[i] = buf[a[0] - 1 - i], buf[a[0] - 1 - i] = ch; for (a[0] = (a[0] + DIGIT - 1) / DIGIT, j = strlen(buf); j < a[0] * DIGIT; buf[j++] = '0'); for (i = 1; i <= a[0]; i++) for (a[i] = 0, j = 0; j<DIGIT; j++) a[i] = a[i] * 10 + buf[i*DIGIT - 1 - j] - '0'; for (; !a[a[0]] && a[0]>1; a[0]--); return 1; } //輸出資料 void BigInteger::write(const bignum_t a, ostream& os = cout) { int i, j; for (os << a[i = a[0]], i--; i; i--) for (j = DEPTH / 10; j; j /= 10) os << a[i] / j % 10; } int BigInteger::comp(const bignum_t a, const int c, const int d, const bignum_t b) { int i, t = 0, O = -DEPTH * 2; if (b[0] - a[0]<d&&c) return 1; for (i = b[0]; i>d; i--){ t = t*DEPTH + a[i - d] * c - b[i]; if (t > 0) return 1; if (t<O) return 0; } for (i = d; i; i--){ t = t*DEPTH - b[i]; if (t>0) return 1; if (t<O) return 0; } return t>0; } /* *大數加法 */ void BigInteger::add(bignum_t a, const bignum_t b) { int i; for (i = 1; i <= b[0]; i++) if ((a[i] += b[i]) >= DEPTH) a[i] -= DEPTH, a[i + 1]++; if (b[0] >= a[0]) a[0] = b[0]; else for (; a[i] >= DEPTH&&i<a[0]; a[i] -= DEPTH, i++, a[i]++); a[0] += (a[a[0] + 1]>0); } /* *大數減法 */ void BigInteger::sub(bignum_t a, const bignum_t b) { int i; for (i = 1; i <= b[0]; i++) if ((a[i] -= b[i]) < 0) a[i + 1]--, a[i] += DEPTH; for (; a[i]<0; a[i] += DEPTH, i++, a[i]--); for (; !a[a[0]] && a[0]>1; a[0]--); } void BigInteger::sub(bignum_t a, const bignum_t b, const int c, const int d) { int i, O = b[0] + d; for (i = 1 + d; i <= O; i++) if ((a[i] -= b[i - d] * c) < 0) a[i + 1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH*DEPTH; for (; a[i]<0; a[i + 1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH*DEPTH, i++); for (; !a[a[0]] && a[0]>1; a[0]--); } /* *大數乘法 */ void BigInteger::mul(bignum_t c, const bignum_t a, const bignum_t b) { int i, j; memset((void*)c, 0, sizeof(bignum_t)); for (c[0] = a[0] + b[0] - 1, i = 1; i <= a[0]; i++) for (j = 1; j <= b[0]; j++) if ((c[i + j - 1] += a[i] * b[j]) >= DEPTH) c[i + j] += c[i + j - 1] / DEPTH, c[i + j - 1] %= DEPTH; for (c[0] += (c[c[0] + 1] > 0); !c[c[0]] && c[0] > 1; c[0]--); } /* *大數除法 */ void BigInteger::div(bignum_t c, bignum_t a, const bignum_t b) { int h, l, m, i; memset((void*)c, 0, sizeof(bignum_t)); c[0] = (b[0]<a[0] + 1) ? (a[0] - b[0] + 2) : 1; for (i = c[0]; i; sub(a, b, c[i] = m, i - 1), i--) for (h = DEPTH - 1, l = 0, m = (h + l + 1) >> 1; h>l; m = (h + l + 1) >> 1) if (comp(b, m, i - 1, a)) h = m - 1; else l = m; for (; !c[c[0]] && c[0] > 1; c[0]--); c[0] = c[0] > 1 ? c[0] : 1; } /* *大數乘方 */ void BigInteger::pow(int b, int n) { time_t start, end;//計時 int *a, i, j; start = time(NULL); a = (int *)malloc(sizeof(int)* MAXSIZE); for (i = 0; i<MAXSIZE; i++) a[i] = 0; a[MAXSIZE-1] = 1; for (i = 1; i<n + 1; i++) { for (j = 0; j<MAXSIZE; j++) a[j] *= b; for (j = MAXSIZE-1; j >= 0; j--) if (a[j] >= 10) { a[j - 1] += a[j] / 10; a[j] %= 10; } } end = time(NULL); for (i = 0; a[i] == 0; i++); for (i; i<MAXSIZE; i++) cout<<a[i]; cout << endl; free(a); cout << "運算耗時:" << difftime(end, start) <<"ms"<< endl; } //運算選擇 void select(int s) { bignum_t a, b, c;//儲存運算值 time_t start, end;//計時 BigInteger big; switch (s){ case 1: cout << "————下面將進行大數加法運算————" << endl; cout << "請輸入大數\na="; big.read(a); cout << "b="; big.read(b); cout << "運算結果:"; big.write(a); cout << "+"; big.write(b); cout << "="; start = time(NULL); big.add(a, b); end = time(NULL); big.write(a); cout << endl; cout << "運算耗時:" << difftime(end, start) << "ms" << endl; break; case 2: cout << "————下面將進行大數減法運算————" << endl; cout << "請輸入大數\na="; big.read(a); cout << "b="; big.read(b); cout << "運算結果:"; big.write(a); cout << "-"; big.write(b); cout << "="; start = time(NULL); big.sub(a, b); end = time(NULL); big.write(a); cout << endl; cout << "運算耗時:" << difftime(end, start) << "ms" << endl; break; case 3: cout << "————下面將進行大數乘法法運算————" << endl; cout << "請輸入大數\na="; big.read(a); cout << "b="; big.read(b); cout << "運算結果:"; big.write(a); cout << "*"; big.write(b); cout << "="; start = time(NULL); big.mul(c, a, b); end = time(NULL); big.write(c); cout << endl; cout << "運算耗時:" << difftime(end, start) << "ms" << endl; break; case 4: cout << "————下面將進行大數除法運算————" << endl; cout << "請輸入大數\na="; big.read(a); cout << "b="; big.read(b); cout << "運算結果:"; big.write(a); cout << "/"; big.write(b); cout << "="; start = time(NULL); big.div(c, a, b); end = time(NULL); big.write(c); cout << endl; cout << "運算耗時:" << difftime(end, start) << "ms" << endl; break; case 5: cout << "————下面將進行大數乘方運算————" << endl; cout << "請輸入大數\na="; int d; cin >> d; cout << "冪\nn="; int n; cin >> n; cout << "運算結果:"<<d<<"^"<<n<<"="; big.pow(d, n); break; default: cout << "輸入非法,請重新輸入!" << endl; break; } } //選單欄 void menu() { cout << endl; cout << "————歡迎使用大數運算系統——————" << endl; cout << "| |" << endl; cout << "|請選擇您將進行的大數運算 |" << endl; cout << "| 1.大數加法 |" << endl; cout << "| 2.大數減法 |" << endl; cout << "| 3.大數乘法 |" << endl; cout << "| 4.大數除法 |" << endl; cout << "| 5.大數乘方 |" << endl; cout << "| 0.退出系統 |" << endl; cout << " ———————————————————" << endl; } int main() { while (1) { menu(); int s; cin >> s; if (!s)break; select(s); } return 0; }