两非负整数的高精度加减乘除模C++模板

2019-04-14 15:54发布

两非负整数的高精度加减乘除模C++


直接打包成一个类模板了,加减法相对来说要简单一点,乘法的实现参考的算法竞赛入门里的bign类,比我之前写的简洁多了–。除法我是直接在有加减乘法的基础上模拟人的算法实现的,有了除法后,模就更简单了= =
其实在这些的基础上,是可以扩展成负数之间的运算的,还可以小数 = = #include #include #include #include #include #include #include #include #include using namespace std; //#define LOCAL const int MAX = 3000 + 10; class Number{ friend ostream& operator<<(ostream &, const Number &); friend istream& operator>>(istream &, Number&); friend Number operator+(const Number&, const Number&); friend Number operator-(const Number&, const Number&); friend Number operator*(const Number&, const Number&); friend Number operator/(const Number&, const Number&); friend Number operator%(const Number&, const Number&); friend Number operator>>(const Number&, int); friend bool operator<(const Number&, const Number&); friend bool operator>(const Number &, const Number &); friend bool operator<=(const Number&, const Number&); friend bool operator>=(const Number &, const Number &); friend bool operator==(const Number &, const Number &); friend bool operator!=(const Number &, const Number &); friend bool operator!=(const Number &, const int &); public: Number() { memset(nums, 0, sizeof(nums)); len = 1; } Number(int num) { memset(nums, 0, sizeof(nums)); *this = num; } Number(const char *num) { memset(nums, 0, sizeof(nums)); *this = num; } Number& operator=(const char* right) { len = strlen(right); for (int i = 0; i < len; ++i) { nums[i] = right[len - i - 1] - '0'; } return *this; } Number& operator=(int right) { char c_right[MAX]; sprintf(c_right, "%d", right); *this = c_right; return *this; } Number& operator=(Number right) { len = right.len; ostringstream ss; ss << right; *this = ss.str().c_str(); return *this; } Number operator>>=(int n) { if (n >= this->len) { *this = 0; } else { int i = 0; for (; n < this->len; ++i, ++n) { this->nums[i] = this->nums[n]; } this->len = i; } return *this; } Number operator+=(const Number &a) { return (*this = *this + a); } Number operator-=(const Number &a) { return (*this = *this - a); } Number operator*=(const Number &a) { return (*this = *this * a); } int& operator[](size_t index) { return this->nums[index]; } const int& operator[](size_t index) const { return this->nums[index]; } int length() const { return len; } string str() const { string str; for (int i = len - 1; i >= 0; --i) { if (nums[MAX] == 1) { str.push_back('-'); } str.push_back(nums[i] + '0'); } return str; } void clearnZero() { while(len > 1 && !nums[len -1]) --len; } static Number pow_Number(Number a, int n) { Number res = 1; while (n--) { res *= a; } return res; } private: int len; int nums[MAX + 1]; }; ostream& operator<<(ostream &out, const Number &num) { out << num.str(); return out; } istream& operator>>(istream &in, Number &num) { string ss; in >> ss; num = ss.c_str(); return in; } Number operator+(const Number &a, const Number &b) { Number res; int len = a.len > b.len ? a.len : b.len; int c = 0; int i; for (i = 0; i < len; ++i) { int sum = 0; if (i < a.len) sum += a.nums[i]; if (i < b.len) sum += b.nums[i]; sum += c; res.nums[i] = sum % 10; c = sum / 10; } if (c) { res.nums[i++] = c; } res.len = i; return res; } Number operator-(const Number &a, const Number &b) { Number res = 0; if (a >= b) { for (int i = 0, c = 0; i < a.len; ++i) { int s = (i < b.len) ? (a[i] - b[i] - c) : (a[i] - c); if (s < 0) { s += 10; c = 1; } else { c = 0; } res[i] = s; } int len; for (len = a.len; len > 1; --len) { if (res[len - 1] != 0) break; } res.len = len; } return res; } Number operator*(const Number &a, const Number &b) { Number res; res.len = a.len + b.len; for (int i = 0; i < a.len; ++i) { for (int j = 0; j < b.len; ++j) { res[i + j] += a.nums[i] * b.nums[j]; } } for (int i = 0; i < res.len - 1; ++i) { res[i + 1] += res[i] / 10; res[i] %= 10; } res.clearnZero(); return res; } Number operator/(const Number &a, const Number &b) { Number a1 = a; Number sum = 0; int c = 0; assert(b != 0); while (a1 >= b) { Number n_10 = Number::pow_Number(10, a1.len - b.len - c); int i = 9; Number inter = 0; for (; i > 0; --i) { inter = b * i * n_10; if (a1 >= inter) { break; } } sum += i * n_10; if (i != 0) { a1 -= inter; c = 0; } else { c += 1; } } return sum; } Number operator%(const Number &a, const Number &b) { Number res = 0; res = a - b * (a / b); return res; } Number operator>>(const Number &a, int n) { Number res = a; return (res >>= n); } bool operator<(const Number &a, const Number &b) { if (a.len != b.len) return a.len < b.len; for (int i = a.len - 1; i >= 0; --i) { if (a.nums[i] != b.nums[i]) return a.nums[i] < b.nums[i]; } return false; } bool operator>(const Number &a, const Number &b) { return (b < a); } bool operator==(const Number &a, const Number &b) { return !(a < b) && !(a > b); } bool operator!=(const Number &a, const Number &b) { return (a > b) || (a < b); } bool operator!=(const Number &a, const int &b) { Number b_num = b; return a != b_num; } bool operator<=(const Number &a, const Number &b) { return !(a > b); } bool operator>=(const Number &a, const Number &b) { return !(a < b); } int main() { #ifdef LOCAL ifstream fin("test.in"); ofstream fout("test.out"); #define cin fin #define cout fout #endif // LOCAL Number a, b; //int a, b; while (cin >> a >> b) { if (a >= b) cout << "a >= b" << endl; cout << a % b << endl; } return 0; }