integer 大整数类型实现

来源:互联网 发布:祖国流氓知乎 编辑:程序博客网 时间:2024/05/16 13:38
#include <iostream>#include <vector>#include <string>using std::string;using std::vector;using std::cin;using std::cout;using std::endl;/*********************************** integer 大整数类型 ******************************************/typedef unsigned int digit;typedef vector<digit> intv;struct integer;integer toint(string s);string tostr(const integer& a);integer intint(int b, digit base = 10);integer operator- (const integer& a);integer operator- (const integer& a, const integer& b);struct integer{integer(const string& s, digit b = 10);integer(digit b = 10, int size = 0);int length()const;int sign() const;bool zero() const {return length() == 0;}void setbase(digit b) { base = b;}integer& operator= (const int a);int operator[] (int) const;bool operator< (const integer& rhs) const;bool operator== (const integer& rhs) const;bool operator!= (const integer& rhs) const;bool operator<= (const integer& rhs) const;bool operator> (const integer& rhs) const;bool operator>= (const integer& rhs) const;integer& operator+=(const integer& a);integer& operator+=(int a);integer& operator-=(const integer& a);integer& operator-=(int a);integer& operator*=(const integer& a);integer& operator*=(int a);integer& operator/=(const integer& a);integer& operator/=(int a);integer& operator++();//前置自增integer operator++(int);//后置自增integer& operator--();integer operator--(int);//datadigit base;//基数bool neg;//符号,负数为truevector<digit> s;//下标从小到大分别为大数的低位到高位};integer::integer(const string& s, digit b):base(b), neg(false){*this = toint(s);}integer::integer(digit b, int size):base(b), neg(false){s.resize(size);}int integer::sign() const{if (neg) return -1;return (length() == 0) ? 0 : 1;}int integer::length() const{int len = s.size();if (len == 0) return 0;while (1){if (s[len-1] == 0){if (--len == 0) return 0;}else break;}return len;}integer& integer::operator= (int a){*this = intint(a, base);return *this;}int integer::operator[] (int i) const{return i >= length() ?  0 : s[i];}bool integer::operator< (const integer& rhs) const{if (neg && !rhs.neg) return true;else if (!neg && rhs.neg) return false;else if (neg && rhs.neg) return (-rhs) < -(*this);else{if (length() > rhs.length()) return false;if (length() < rhs.length()) return true;else {for (int i = length()-1; i >= 0; --i){if (s[i] > rhs.s[i]) return false;else if (s[i] < rhs.s[i]) return true;}return false;}}}bool integer::operator== (const integer& rhs) const{if (neg != rhs.neg) return false;else{if (length() != rhs.length()) return false;else {for (int i = length()-1; i >= 0; --i){if (s[i] != rhs.s[i]) return false;}return true;}}}bool integer::operator!= (const integer& rhs) const{return !(*this == rhs);}bool integer::operator<= (const integer& rhs) const{if (*this < rhs || *this == rhs) return true;else return false;}bool integer::operator> (const integer& rhs) const{return rhs < *this;}bool integer::operator>= (const integer& rhs) const{return rhs <= *this;}integer operator- (const integer& a){integer b(a);b.neg = !b.neg;return b;}std::istream& operator>> (std::istream& in, integer& a){string str;in >> str;a = toint(str);return in;}std::ostream& operator<< (std::ostream& out, const integer& a){out << tostr(a);return out;}integer toint(string s){integer c;if (s.empty()) return c;if (s[0] == '-'){c.neg = true;s = s.substr(1);}else c.neg = false;c.s.resize(s.length());for (unsigned i = 0; i < s.length(); ++i){digit tmp = (digit)s[s.length()-1-i];if (tmp >= '0' && tmp <= '9') c.s[i] = tmp - '0';else if (tmp >= 'a' && tmp <= 'z') c.s[i] = tmp - 'a';else if (tmp >= 'A' && tmp <= 'Z') c.s[i] = tmp - 'A';}return c;}string tostr(const integer& a){string str = (a.neg ? "-" : "");if (a.length() == 0)str += '0';for (int i = a.length()-1; i >= 0; --i){if (a.s[i] < 10) str += a.s[i] + '0';else str += a.s[i] - 10 + 'A';}return str;}integer intint(int b, digit base){integer c;c.neg = false;if (b == 0) {c.s.push_back(0);return c;}if (b < 0){c.neg = true;b = -b;}while (b){c.s.push_back(b % base);b = b/base;}return c;}void adder(digit a, digit b, digit c, digit& s, digit& cr, digit base){digit sum = a + b + c;cr = sum / base;s = sum % base;}void dmult(digit a, digit b, digit& s, digit& cr, digit base){digit p = a * b;cr = p / base;s = p % base;}digit digi(const intv& a, int i){return i < (int)a.size() ? a[i] : 0 ;}intv add(const intv& a, const intv& b, digit base){int n = std::max(a.size(), b.size());intv s(n+1);digit cr = 0;for (int i = 0; i < n; ++i){adder(digi(a, i), digi(b, i), cr, s[i], cr, base);}s[n] = cr;return s;}void sub(intv& a, const intv& b, digit base){digit cr = 0;for (int i = 0; i < (int)a.size(); ++i){if (a[i] >= digi(b, i) + cr){a[i] = a[i] - digi(b, i) - cr;cr = 0;}else{a[i] = a[i] + base - digi(b, i) -cr;cr = 1;}}}void mult(const intv& a, const digit& b, intv& ab, digit base){int n = a.size();//assert(ab.size() == n + 1);digit cr = 0, c, d, cp = 0;for (int i = 0; i < n; ++i){dmult(a[i], b, d, c, base);adder(d, cp, cr, ab[i], cr, base);cp = c;}d = 0;adder(d, cp, cr, ab[n], cr, base);}void addj(intv& p, const intv& abj, int j, digit base){digit cr = 0;int d= p.size();for (int i = j; i < d; ++i){adder(p[i], digi(abj, i - j), cr, p[i], cr, base);}}intv mult(const intv& a, const intv& b, digit base){int n = a.size();int m = b.size();intv p(n + m, 0);intv abj(n + 1);for (int j = 0; j < m; ++j){mult(a, b[j], abj, base);addj(p, abj, j, base);}return p;}integer operator* (const integer& a, const integer& b){integer c(a.base);if(a.zero()) return a;if(b.zero()) return b;if((a.neg && !b.neg) || (b.neg && !a.neg)) c.neg = true;else c.neg = false;c.s = mult(a.s, b.s, c.base);return c;}integer operator* (const integer& a, int b){return a * intint(b, a.base);}integer operator* (int a, const integer& b){return intint(a, b.base) * b;}integer operator+ (const integer& a, const integer& b){if (a.zero()) return b;if (b.zero()) return a;if (a.neg && !b.neg) return b - -a;if (!a.neg && b.neg) return a - -b;integer c;c.s = add(a.s, b.s, a.base);c.neg = a.neg;return c;}integer operator+ (const integer& a, int b){return a + intint(b, a.base);}integer operator+ (int b, const integer& a){return intint(b, a.base) + a;}integer operator- (const integer& a, const integer& b){if (a.zero()) return -b;if (b.zero()) return a;if (a < b) return -(b - a);if (a.neg && !b.neg) return -(-a + b);if (!a.neg && b.neg) return a + -b;if (a.neg && b.neg) return -(-a - -b);integer c(a.base);c.s = a.s;sub(c.s, b.s, c.base);return c;}integer operator- (const integer& a, int b){return a - intint(b, a.base);}integer operator- (int b, const integer& a){return intint(b, a.base) - a;}integer operator/ (const integer& a, const integer& b){digit base = a.base;integer c(base, a.length()), d(base, b.length());if (a.zero() || b.zero()) return a;if ((b.neg && !a.neg) || (a.neg && !b.neg)) c.neg = true; else c.neg = false;for (int i = a.length() -1; i >= 0; --i){d = d * base + a.s[i];while(!(d < b)){d = d - b;++c.s[i];}}return c;}integer operator/ (const integer& a, int b){return a / intint(b, a.base);}integer operator/ (int b, const integer& a){return intint(b, a.base) / a;}integer operator% (const integer& a, const integer& b){digit base = a.base;integer c(base, a.length()), d(base, b.length());if (a.zero() || b.zero()) return a;if ((b.neg && !a.neg) || (a.neg && !b.neg)) c.neg = true; else c.neg = false;for (int i = a.length() -1; i >= 0; --i){d = d * base + a.s[i];while(!(d < b)){d = d - b;++c.s[i];}}return d;}integer operator% (const integer& a, int b){return a % intint(b, a.base);}integer operator% (int b, const integer& a){return intint(b, a.base) % a;}integer& integer::operator+=(const integer& a){*this = *this + a;return *this;}integer& integer::operator+=(int a){*this = *this + a;return *this;}integer& integer::operator-=(const integer& a){*this = *this - a;return *this;}integer& integer::operator-=(int a){*this = *this - a;return *this;}integer& integer::operator*=(const integer& a){*this = *this * a;return *this;}integer& integer::operator*=(int a){*this = *this * a;return *this;}integer& integer::operator/=(const integer& a){*this = *this / a;return *this;}integer& integer::operator/=(int a){*this = *this / a;return *this;}integer& integer::operator++(){*this = *this + 1;return *this;}integer integer::operator++(int){integer c(*this);*this = *this + 1;return c;}integer& integer::operator--(){*this = *this - 1;return *this;}integer integer::operator--(int){integer c(*this);*this = *this - 1;return c;}/*************************************** end integer ************************************************///用大整数类型计算阶乘integer fact(int n, digit base){integer f(base);f = 1;for (int i = 2; i <= n; ++i)f = f * i;return f;}int main(void){integer a;a = fact(100, 10);cout << a <<endl;system("pause");return 0;}


 

原创粉丝点击