大整数类 模板
自己写的大整数模板,已经升级到V2.0
功能:
计算大整数加减乘数取模运算,支持无限位数,支持正负数输入输出及运算,支持判断两个大整数的大小
保障:
1.VC++2013,GCC4.7.3运行测试通过
2.学校OJ加减乘除取模均AC
//BigInt V2.0 //By KunSoft #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <cmath> #include <deque> #include <iterator> #include <algorithm> using namespace std; typedef long long LLT; class BigInt { public: BigInt() :negative(false) {} BigInt(const LLT); BigInt(const char*); BigInt(const string); BigInt(const BigInt & x); BigInt & operator = (const BigInt &); friend istream & operator >> (istream &, BigInt &); friend ostream & operator << (ostream &, BigInt); BigInt operator + (const BigInt &) const; BigInt operator - (const BigInt &) const; BigInt operator * (const BigInt &) const; BigInt operator / (const LLT &) const; LLT operator % (const LLT &) const; bool operator > (const BigInt &) const; bool operator == (const BigInt &) const; bool operator >= (const BigInt &) const; friend BigInt abs(const BigInt &); BigInt operator - () const; private: deque<int> num; bool negative; }; BigInt::BigInt(const LLT x){ LLT t = abs(x); negative = x >= 0 ? true : false; while (t > 0){ num.push_back(t % 10); t = t / 10; } } BigInt::BigInt(const char* str){ unsigned i = str[0] == '-' ? 1 : 0; this->negative = str[0] == '-' ? true : false; for (; i < strlen(str); ++i) num.push_back(str[i] - '0'); } BigInt::BigInt(const string str){ unsigned i = str[0] == '-' ? 1 : 0; this->negative = str[0] == '-' ? true : false; for (; i < str.size(); ++i) num.push_back(str[i] - '0'); } BigInt::BigInt(const BigInt &x){ negative = x.negative; num = x.num; } BigInt & BigInt::operator = (const BigInt &x){ negative = x.negative; num = x.num; return (*this); } istream & operator >> (istream &is, BigInt & x){ string str; is >> str; x = str; return is; } ostream & operator << (ostream &os, BigInt x){ if (x.negative) os << '-'; for (unsigned i = 0; i != x.num.size(); ++i) os << x.num[i]; return os; } bool BigInt::operator > (const BigInt & rhs) const { BigInt x = (*this), y = rhs; if (!x.negative && y.negative) return true; if (x.negative && !y.negative) return false; if (x.negative && y.negative) swap(x, y); if (x.num.size() > y.num.size()) return true; if (x.num.size() < y.num.size()) return false; for (unsigned i = 0; i != x.num.size(); ++i) { if (x.num[i] > y.num[i]) return true; if (x.num[i] < y.num[i]) return false; } return false; } bool BigInt::operator == (const BigInt & rhs) const { return negative == rhs.negative && num == rhs.num; } bool BigInt::operator >= (const BigInt & rhs) const { return *this > rhs || *this == rhs; } BigInt abs(const BigInt & rhs){ BigInt res; res.negative = false; res.num = rhs.num; return res; } BigInt BigInt::operator - () const { BigInt ret = *this; ret.negative = !ret.negative; return ret; } BigInt BigInt::operator + (const BigInt & y) const { if (!this->negative && y.negative) return *this - abs(y); if (this->negative && !y.negative) return y - abs(*this); if (this->negative && y.negative) return -(abs(*this) + abs(y)); BigInt x = *this, res; int temp = 0; for (int i = x.num.size() - 1, j = y.num.size() - 1; i >= 0 || j >= 0; --i, --j) { int a = i < 0 ? 0 : x.num[i]; int b = j < 0 ? 0 : y.num[j]; res.num.push_front((a + b + temp) % 10); temp = (a + b + temp) / 10; } if (temp != 0) res.num.push_front(temp); return res; } BigInt BigInt::operator * (const BigInt & y) const { deque<int> a, b, res; copy(this->num.begin(), this->num.end(), front_inserter(a)); copy(y.num.begin(), y.num.end(), front_inserter(b)); res.resize(a.size() + b.size() + 5); for (unsigned i = 0; i < a.size(); ++i) for (unsigned j = 0; j < b.size(); ++j) res[i + j] += a[i] * b[j]; for (unsigned i = 0; i < res.size() - 1; ++i){ res[i + 1] += res[i] / 10; res[i] %= 10; } while (res.size() >= 2 && res.back() == 0) res.pop_back(); reverse(res.begin(), res.end()); BigInt ret; ret.negative = this->negative ^ y.negative; ret.num = res; return ret; } BigInt BigInt::operator - (const BigInt & y) const { if (!this->negative && y.negative) return *this + abs(y); if (this->negative && !y.negative) return -(abs(*this) + y); if (this->negative && y.negative) return abs(y) - abs(*this); deque<int> a, b, res; BigInt ret; copy(this->num.begin(), this->num.end(), front_inserter(a)); copy(y.num.begin(), y.num.end(), front_inserter(b)); if (y > *this) swap(a, b), ret.negative = true; res.resize(max(a.size(), b.size()) + 5); for (unsigned i = 0, j = 0; i < a.size() || j < b.size(); ++i, ++j){ int m = i < a.size() ? a[i] : 0; int n = j < b.size() ? b[j] : 0; res[i] = m - n; } for (unsigned i = 0; i < res.size() - 1; ++i) if (res[i] < 0) { res[i] += 10; --res[i + 1]; } while (res.size() >= 2 && res.back() == 0) res.pop_back(); reverse(res.begin(), res.end()); ret.num = res; return ret; } BigInt BigInt::operator / (const LLT & y) const { LLT temp = 0; BigInt x = (*this), res; for (unsigned i = 0; i < x.num.size(); ++i){ temp = temp * 10 + x.num[i]; res.num.push_back((int)(temp / y)); temp %= y; } while (res.num.size() >= 2 && res.num.front() == 0) res.num.pop_front(); return res; } LLT BigInt::operator % (const LLT & y) const { LLT res = 0; for (unsigned i = 0; i < this->num.size(); ++i) res = (res * 10 + this->num[i]) % y; return res; } int main() { BigInt a, b; while (cin >> a >> b) cout << a + b << endl; return 0; }
下面是老版的V1.0版本提供参考,使用数组实现,速度会快一些。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <cmath> #include <algorithm> #define MAXN 1024 using namespace std; class BigInt { private: int num[MAXN]; int len; int flag; public: BigInt() { memset(num, 0, sizeof(num)); len = 0; flag = 1; }; BigInt(const int); BigInt(const char*); BigInt(const string); BigInt(const BigInt &x); BigInt &operator = (const BigInt &); friend istream &operator >> (istream &, BigInt &); friend ostream &operator << (ostream &, BigInt &); BigInt operator + (const BigInt &); BigInt operator - (const BigInt &); BigInt operator * (const BigInt &); BigInt operator / (const long long int &); long long int operator % (const long long int &); bool operator > (const BigInt &); friend BigInt rev(const BigInt &x); }; //将一个int类型的变量转化为BigInt类型 BigInt::BigInt(const int x) { memset(num, 0, sizeof(num)); len = 0; int t; if(x < 0) { t = -x; flag = -1; } else t = x; while (t > 0) { num[len++] = t % 10; t = t / 10; } } //将一个C风格字符串的变量转化为BigInt类型 BigInt::BigInt(const char* str) { memset(num, 0, sizeof(num)); len = strlen(str); for (int i = 0; i < len; i++) { num[i] = str[i] - '0'; } } //将一个string字符串的变量转化为BigInt类型 BigInt::BigInt(const string str) { string temp(str); memset(num, 0, sizeof(num)); len = temp.size(); int cnt = 0; for (string::iterator i = temp.begin(); i != temp.end(); i++) num[cnt++] = *i - '0'; } //拷贝BigInt对象 BigInt::BigInt(const BigInt &x) { len = x.len; flag = x.flag; memset(num, 0, sizeof(num)); for (int i = 0; i < len; i++) num[i] = x.num[i]; } //重载赋值运算符 BigInt & BigInt::operator = (const BigInt &x) { len = x.len; flag = x.flag; memset(num, 0, sizeof(num)); for (int i = 0; i < len; i++) num[i] = x.num[i]; return (*this); } //重载输入运算符 istream &operator >> (istream &is, BigInt &x) { string temp; is >> temp; memset(x.num, 0, sizeof(x.num)); x.len = temp.size(); int cnt = 0; for (string::iterator i = temp.begin(); i != temp.end(); i++) x.num[cnt++] = *i - '0'; return is; } //重载输出运算符 ostream &operator << (ostream &os, BigInt &x) { if(x.flag == -1) printf("-"); for (int i = 0; i < x.len; i++) printf("%d", x.num[i]); return os; } //获取翻转BigInt后的BigInt BigInt rev(const BigInt &x) { BigInt res; res.len = x.len; res.flag = x.flag; memset(res.num, 0, sizeof(res.num)); for(int i=0; i<res.len; i++) res.num[res.len-1-i] = x.num[i]; return res; } //判断两个BigInt的大小 bool BigInt::operator > (const BigInt &y) { BigInt x = (*this); if(x.len > y.len) return true; else if(x.len < y.len) return false; else if(x.len == y.len) { for(int i=0; i<x.len; i++) { if(x.num[i] > y.num[i]) return true; else if(x.num[i] < y.num[i]) return false; } return false; } } //两个BigInt之间的加法运算 BigInt BigInt::operator + (const BigInt &y) { BigInt x(*this); BigInt res; int i, j; int cnt = 0, temp = 0; for (i = x.len - 1, j = y.len - 1; i >= 0 || j >= 0; i--, j--) { int a = i < 0 ? 0 : x.num[i]; int b = j < 0 ? 0 : y.num[j]; res.num[cnt++] = (a + b + temp) % 10; temp = (a + b + temp) / 10; } if (temp != 0) res.num[cnt++] = temp; res.len = cnt; for (int i = 0; i < (res.len / 2); i++) { int t = res.num[i]; res.num[i] = res.num[res.len - 1 - i]; res.num[res.len - 1 - i] = t; } return res; } //两个BigInt之间的乘法运算 BigInt BigInt::operator * (const BigInt &y) { BigInt a, b, res; BigInt ret; a = rev(*this); b = rev(y); for(int i=0; i<a.len; i++) for(int j=0; j<b.len; j++) res.num[i+j] += a.num[i] * b.num[j]; for(int i=0; i<MAXN-1; i++) { res.num[i+1] += res.num[i]/10; res.num[i] = res.num[i]%10; } for(int i = MAXN-1; i>=0; --i) { if(res.num[i]!=0) { res.len = i + 1; break; } } if(res.len==0) { res.len = 1; res.num[0] = 0; } ret = rev(res); return ret; } //两个BigInt之间的减法运算 BigInt BigInt::operator - (const BigInt &y) { BigInt a = rev(*this), b = rev(y); BigInt res, ret; if(b > a) { swap(a, b); res.flag = -1; } for(int i=0, j=0; i<a.len || j<b.len; i++, j++) { int m = i<a.len ? a.num[i] : 0; int n = j<b.len ? b.num[j] : 0; res.num[i] = m - n; } for(int i=0; i<MAXN-1; i++) { if(res.num[i]<0) { res.num[i] += 10; res.num[i+1]--; } } for(int i = MAXN-1; i>=0; --i) { if(res.num[i]!=0) { res.len = i + 1; break; } } if(res.len==0) { res.len = 1; res.num[0] = 0; } ret = rev(res); return ret; } //BigInt除以一个长整形运算 BigInt BigInt::operator / (const long long int &y) { long long int temp = 0; BigInt x = (*this); BigInt res; for(int i=0; i<len; i++) { temp = temp*10 + x.num[i]; res.num[i] = temp / y; temp = temp % y; } //去前导0 int cnt = 0; for(int i = 0; i<MAXN; ++i) { if(res.num[i]!=0) { cnt = i; break; } } for(int i = cnt; i<MAXN; ++i) { int t = res.num[i]; res.num[i] = res.num[i-cnt]; res.num[i-cnt] = t; } res.len = x.len - cnt; return res; } //BigInt对一个长整形做取余运算 long long int BigInt::operator % (const long long int &y) { long long int temp = 0; BigInt x = (*this); BigInt res; for(int i=0; i<len; i++) { temp = temp*10 + x.num[i]; res.num[i] = temp / y; temp = temp % y; } return temp; } int main() { return 0; }