C++大数类

来源:互联网 发布:软件项目成本核算方法 编辑:程序博客网 时间:2024/06/08 18:22

大整数类

1.功能

  1. 支持无限长(2^31位)的整数的加、减、乘、除运算;
  2. 支持有符号整数;
  3. 支持流输入、输出;
  4. 支持 >,  >=, <, <=, ==, != 等比较操作。

2.细节

  1. 利用string存储大整数的各位数据,一位十进制数用一个char存放;
  2. 加法、减法、乘法、除法以整数十进制形式的位为单位进行加法、减法、乘法、除法后求和;
  3. 除法中商的每一位,从0到9试探得出;

3.其他

  1. 使用C++写成, 在g++上调试通过;
  2. 也许仍有部分问题。

4.代码

/*************************************************************************    > File Name: Integer.cpp    > Mail: hpxiangsky@gmail.com     > Created Time: Fri 12 Apr 2013 09:53:30 AM CST ************************************************************************//************************************************************************** History: *       1. May 4th, 2013,  fixed a bug of eraze preceding zeros.*       1. May 1st, 2013,  adding support for /.*       2. Apr 12th 2013,  adding support for singed Integer. *       3. Dec 20th 2012,  support calculations(+ - *) that will not overflow.** Class Presentation:*       1. calculation including + - * *       2. support signed Integer.*************************************************************************/#include <string>#include <iostream>#include <stdio.h>using namespace std;class Integer{public:Integer();~Integer();                                                Integer(const Integer &rhs);//利用Integer类初始化Integer(const string &s);//利用string类初始化 Integer(const char *s);//利用字符串初始化Integer(int s);//利用int 初始化public:    //四则运算重载,逻辑>, < , == 等重载Integer &operator=(const Integer &);const Integer operator +(const Integer &) const;const Integer operator -(const Integer &) const;const Integer operator *(const Integer &) const;  const Integer operator /(const Integer &) const;const Integer operator ++();const Integer operator ++(int);const Integer operator --();const Integer operator --(int);const Integer operator +=(const Integer &);const Integer operator -=(const Integer &);const Integer operator *=(const Integer &);const Integer operator /=(const Integer &);bool operator == (const Integer &) const;bool operator != (const Integer &) const;bool operator > (const Integer &) const;bool operator >= (const Integer &) const;bool operator < (const Integer &) const;bool operator <= (const Integer &) const;//输入、输出重载friend ostream & operator<<(ostream &, const Integer &);friend istream & operator>>(istream &, Integer &);private:int compare(const Integer &) const;//比较大小函数const Integer abs(const Integer &) const;       //取绝对值函数const Integer absPlus(const Integer &, const Integer &) const;   //绝对值加const Integer absMinus(const Integer &, const Integer &) const;  //绝对值减void erasePreZero(void);                        //去除开始的0private:string*data;                                  //利用string来存放数据boolsgn;        //符号, 0为正(或0),1为负};Integer::Integer():data(NULL), sgn(false){}Integer::Integer(const string &s){if(s[0] == '-'){sgn = true;data = new string(s.substr(1));}else{sgn = false;data = new string(s);}erasePreZero();}Integer::Integer(const char *s){*this = Integer(string(s));}Integer::Integer(int num){char buf[10];if(num < 0){sgn = true;num = -num;}elsesgn = false;sprintf(buf, "%d", num);data = new string(buf);}Integer::Integer(const Integer &rhs){sgn = rhs.sgn;data = new string(*rhs.data);}Integer::~Integer(){delete data;}//去除开始的0void Integer::erasePreZero(void){unsigned int si = 0;while(data->at(si) == '0' && si < data->size() - 1)    ++si;*data = data->substr(si);}//赋值重载Integer &Integer::operator=(const Integer &rhs){if(this == &rhs)return *this;delete data;data = NULL;data = new string(*rhs.data);sgn = rhs.sgn;return *this;}//加法重载const Integer Integer::operator+(const Integer &rhs) const{Integer num1(*this);Integer num2(rhs);//判断是绝对值相加还是相减,结果的符号,并使绝对值大者放在第一位bool isPlus = !(num1.sgn ^ num2.sgn);//绝对值相加还是相减bool absLarger = abs(num1) > abs(num2);//绝对值的大小int flag;//结果的符号, 1为负, 0为正if(isPlus)flag = num1.sgn;elseflag = !(num1.sgn ^ absLarger); if(!absLarger){Integer tmp(num2);num2 = num1;num1 = tmp;}Integer result;if(isPlus)result = absPlus(num1, num2);elseresult = absMinus(num1, num2);if(result == 0)flag = 0;if(flag)return result * (-1);elsereturn result;}//左++函数const Integer Integer::operator++(){*this = *this + 1;return *this;}//右++函数const Integer Integer::operator++(int){Integer tmp = *this;*this = *this + 1;return tmp;}const Integer Integer::operator+=(const Integer &num2){*this = *this + num2;return *this;}//减法重载const Integer Integer::operator-(const Integer &rhs) const {    Integer tmp(rhs);tmp.sgn = !tmp.sgn;return *this + tmp;}//左--函数const Integer Integer::operator--(){*this = *this - 1;return *this;}//右--函数const Integer Integer::operator--(int){Integer tmp = *this;*this = *this - 1;return tmp;}const Integer Integer::operator-=(const Integer &rhs){*this = *this - rhs;return *this;}//取绝对值const Integer Integer::abs(const Integer &num1) const{Integer r(num1);r.sgn = 0;return r;}//绝对值相加const Integer Integer::absPlus(const Integer &num1, const Integer &num2) const{string r;int len1 = num1.data->size(), len2 = num2.data->size(), maxLen; if(len1 >= len2)maxLen = len1;elsemaxLen = len2;int s, ad = 0, d1, d2;for(int i = 1;i <= maxLen;++i){    d1 = i <= len1 ? num1.data->at(len1 - i) - '0' : 0;    d2 = i <= len2 ? num2.data->at(len2 - i) - '0' : 0;s = d1 + d2 + ad; ad = s / 10;s = s % 10;r = string(1, s + '0') + r; }if(ad)r = '1' + r;return Integer(r);}//绝对值相减(需要num1 >= num2)const Integer Integer::absMinus(const Integer &num1, const Integer &num2) const{string r;int len1 = num1.data->size(), len2 = num2.data->size(), maxLen = len1;int s, ad = 0, d1, d2;for(int i = 1;i <= maxLen;++i){d1 = num1.data->at(len1 - i) - '0';d2 = i <= len2 ? num2.data->at(len2 - i) - '0' : 0;s = d1 - d2 - ad; if (s < 0){ad = 1;s += 10;}elsead = 0;r = string(1, s + '0') + r; }    Integer result(r);    result.erasePreZero();return result;}//乘法重载const Integer Integer::operator*(const Integer &rhs) const{Integer result(0);if(rhs == -1){result = *this;result.sgn = !sgn;return result;}int len1 = data->size(), len2 = rhs.data->size();int d1, d2, ad, s;string r;for(int i = 1; i <= len1;++i){r.clear();d1 = data->at(len1 - i) - '0';ad = 0;for(int j = 1;j <= len2;++j){d2 = rhs.data->at(len2 - j) - '0';s = d1 * d2 + ad;ad = s / 10;s = s % 10;r = string(1, s + '0') + r;}if(ad > 0)r = string(1, ad + '0') + r;r = r + string(i-1, '0');Integer tmp(r);result += tmp; }if(sgn ^ rhs.sgn)result.sgn = 1;elseresult.sgn = 0;return result;}const Integer Integer::operator *=(const Integer &num2){*this = (*this) *  num2;return *this;}//除法const Integer Integer::operator/(const Integer &divisor) const{int len1 = data->size(), len2 = divisor.data->size();if(len1 < len2){return 0;}//计算商int si = -1;string r;Integer left, dividend = data->substr(0, len2);while(1){int qr = 0;//通过试探法得出商的各位while( abs(divisor) * (qr+1) <= abs(dividend)) ++qr;r = r + string(1, qr + '0');left = dividend - abs(divisor) * qr;++si;if(si + len2 < len1)dividend = Integer(*(left.data) + data->substr(si+len2, 1));elsebreak;}//去除开始的0while(r.find('0') == 0 && r.size() > 1){r = r.substr(1);}Integer result(r);result.sgn = sgn ^ divisor.sgn;return result;}const Integer Integer::operator/=(const Integer &num2){*this = (*this)/ num2;return *this;}bool Integer::operator > (const Integer &num2) const{int r = compare(num2);if(r == 1)return true;return false;}bool Integer::operator < (const Integer &num2) const{int r = compare(num2);if( r == -1)return true;return false;}bool Integer::operator <= (const Integer &num2) const{int r = compare(num2);if( r == -1 || r == 0)return true;return false;}bool Integer::operator >= (const Integer &num2) const{int r = compare(num2);if( r == 1 || r== 0)return true;return false;}bool Integer::operator == (const Integer &num2) const{int r = compare(num2);if( r == 0)return true;return false;}bool Integer::operator != (const Integer &num2) const{int r = compare(num2);if( r != 0)return true;return false;}//比较函数//返回值为1表示大于,0表示等于,-1表示小于int Integer::compare(const Integer &num2) const{//正负不同时if(sgn == 0 && num2.sgn == 1)return 1;if(sgn == 1 && num2.sgn == 0)return -1;//正负相同时int len1 = data->size(), len2 = num2.data->size();int abs = len1 - len2;if(abs == 0)//长度相同{for(int i = 0; i < len1;++i)//从高位到低位依次比较{abs = (int)(data->at(i)) - (int)(num2.data->at(i));if(abs != 0)break;}}if(abs > 0)abs = 1;if(abs < 0) abs = -1;return abs;}//输出重载ostream &operator << (ostream &out, const Integer &rhs){if(rhs.sgn == 1)out << "-";out << *rhs.data;return out;}//输入重载istream & operator>>(istream &in, Integer &rhs){string a;in >> a;if(a[0] == '-'){rhs.sgn = 1;a = a.substr(1);}elserhs.sgn = 0;rhs.data = new string(a);return in;}int main(){Integer n1, n2;cout << "input a Integer n1" << endl;cin >> n1;                                  // -12334213123123123cout << "input a Integer n2" << endl;cin >> n2;                                 // 234124141     Integer n3(n2);cout << "n3 = n1 = " << (n3 =  n1) << endl;cout << "n1 + n2 = " << n1 + n2 << endl;cout << "n1 - n2 = " << n1 - n2 << endl;cout << "n1 * n2 = " << n1 * n2 << endl;cout << "++n1 = " << ++n1  << endl;cout << "n1++ = " << n1++  << endl;cout << "--n1 = " << --n1  << endl;cout << "n1-- = " << n1--  << endl;cout << "n1 += n2 = " << (n1+=n2) << endl;cout << "n1 -= n2 = " << (n1-=n2) << endl;cout << "n1 / n2 =" << n1 / n2 << endl;cout << "n1 /= n2 =" << (n1 /= n2) << endl;cout << "n1 *= n2 =" << (n1 *= n2) << endl;return 0;}