大整数处理类(cpp文件)

///////////////////////integer.cpp

#include "integer.h"

BigInteger::BigInteger()

{

    sign = 0;

    ndigit = 1;

    modulus[0] = '0';

    memset(modulus + 1,'\0',MAXSIZE - 1);

}

 

BigInteger::~BigInteger()

{

 

}

 

BigInteger::BigInteger(const char* a)

{

    memset(modulus,'\0',MAXSIZE);

 

    sign = (a[0] == '-') ? 1 : 0;

 

    int pos = sign;

 

    while('\0' != a[pos])

    {

       modulus[pos - sign] = a[pos++];

    }

 

    ndigit = pos - sign;

 

    modulus[ndigit] = '\0';

}

 

BigInteger::BigInteger(const int& another)

{

    memset(modulus,'\0',MAXSIZE);

 

    int an = another;

    if(0 == an)

    {

       sign = 0;

       ndigit = 1;

       modulus[0] = '0';

       modulus[1] = '\0';

       return;

    }

    else if(an > 0)

       sign = 0;

    else

    {

       sign = 1;

       an = -an;

    }

    int tmp[256] = {0};

 

    int i = 0;

    while(0 < an)

    {

       tmp[i++] = an % 10;

       an /= 10;

    }

    ndigit = i;

    for(i = 0;i < ndigit;i++)

    {

       modulus[i] = tmp[ndigit - 1 - i] + '0';

    }

    modulus[ndigit] = '\0';

}

 

BigInteger::BigInteger(const BigInteger& another)

{

    memset(modulus,'\0',MAXSIZE);

    sign = another.sign;

    ndigit = another.ndigit;

    memcpy(modulus,another.modulus,another.ndigit);

}

 

BigInteger BigInteger::abs(const BigInteger& another)

{

    BigInteger newBigInteger = another;

    newBigInteger.sign = 0;

    return newBigInteger;

}

BigInteger BigInteger::mod(const BigInteger& another)

{

    return (*this % another);

}

BigInteger BigInteger::gcd(const BigInteger& another)

{

    return (gcd(*this,another));

}

BigInteger BigInteger::gcd(const BigInteger& a1, const BigInteger& a2)

{

    if((BigInteger("0") == a1) || (BigInteger("0") == a2))

    {

       BigInteger result;

       memcpy(result.modulus,"error",6);

       return result;

    }

    BigInteger a = abs(a1);

    BigInteger b = abs(a2);

    BigInteger c;

    if(a < b)

    {

       c = a;

       a = b;

       b = c;

    }

    while(b > BigInteger("0"))

    {

       c = a % b;

       a = b;

       b = c;

    }

    return a;

}

BigInteger BigInteger::lcm(const BigInteger& another)

{

    return (lcm(*this,another));

}

BigInteger BigInteger::lcm(const BigInteger& a1, const BigInteger& a2)

{

    if((BigInteger("0") == a1) || (BigInteger("0") == a2))

    {

       return BigInteger("0");

    }

    BigInteger a = a1;

    BigInteger b = a2;

    return (a * b / gcd(a,b));

}

BigInteger& BigInteger::operator = (const BigInteger& another)

{

    sign = another.sign;

    ndigit = another.ndigit;

    memcpy(modulus,another.modulus,MAXSIZE);

 

    return *this;

}

 

BigInteger& BigInteger::operator = (const string& another)

{

    sign = (another[0] == '-') ? 1 : 0;

 

    int pos = sign;

 

    while('\0' != another[pos])

    {

       modulus[pos - sign] = another[pos++];

    }

 

    ndigit = pos - sign;

    modulus[ndigit] = '\0';

 

    return *this;

}

 

BigInteger& BigInteger::operator = (const int& another)

{

    int an = another;

    if(0 == an)

    {

       sign = 0;

       ndigit = 1;

       modulus[0] = '0';

       modulus[1] = '\0';

       return *this;

    }

    else if(an > 0)

       sign = 0;

    else

    {

       sign = 1;

       an = -an;

    }

    int tmp[256] = {0};

 

    int i = 0;

    while(0 < an)

    {

       tmp[i++] = an % 10;

       an /= 10;

    }

    ndigit = i;

    for(i = 0;i < ndigit;i++)

    {

       modulus[i] = tmp[ndigit - 1 - i] + '0';

    }

    modulus[ndigit] = '\0';

 

    return *this;

}

/**

* 重载+运算符(-,*,/,%与其相同)

 

* 这里应该是值返回,因为值返回会产生临时变量,临时变量与局部变量result的复制

会进入到拷贝构造函数中,重新拷贝一份,局部变量result在运行完拷贝构造函数后才

会被释放掉;

若返回引用,则不会产生临时变量,函数结束后不会进入到拷贝构造函数,而函数运

行结束后,result变量已经被释放,即返回值所引用的对象已经被释放,就会指向一个

无效的值,即结果错误。

 

@param another 进行加运算的第二个操作符

 

@return 运算的结果

*/ 

BigInteger BigInteger::operator + (const BigInteger& another)

{

    bool signSame = !(sign ^ another.sign);

 

    if(signSame)

    {

       if(0 == sign)

       {

           BigInteger result;

           int nlunker = max(ndigit,another.ndigit);

 

           int residue = 0;

           for(int i = 0;i < nlunker;++i)

           {

              int a1 = ((ndigit - 1 - i) >= 0) ? (modulus[ndigit - 1 - i] - '0') : 0;

              int a2 = ((another.ndigit - 1 - i) >= 0) ? (another.modulus[another.ndigit - 1 - i] - '0') : 0;

              residue += a1 + a2;

 

              result.modulus[nlunker - i] = (residue % 10) + '0';

              residue /= 10;

           }

           if(residue > 0)

           {

              result.modulus[0] = residue + '0';

              result.sign = 0;

              result.ndigit = nlunker + 1;

              result.modulus[result.ndigit] = '\0';

              return result;

           }

           else

           {

              BigInteger r1;

              r1.sign = 0;

              r1.ndigit = nlunker;

              memcpy(r1.modulus,result.modulus+1,nlunker);

 

              r1.modulus[r1.ndigit] = '\0';

              return r1;

           }

       }

       else

       {

           BigInteger a1 = *this;

           BigInteger a2 = another;

           a1.sign = a2.sign = 0;

 

           return -(a1 + a2);

       }

    }

    else

    {

       if(0 == sign)

       {

           BigInteger a2 = *this;

           BigInteger a1 = another;

           a1.sign = 0;

           return a2 - a1;

       }

       else

       {

           BigInteger a2 = another;

           BigInteger a1 = *this;

           a1.sign = 0;

           return a2 - a1;

       }

    }

}

 

BigInteger& BigInteger::operator += (const BigInteger& another)

{

    *this = *this + another;

    return *this;

}

 

BigInteger BigInteger::operator - (const BigInteger& another)

{

    bool signSame = !(sign ^ another.sign);

    if(signSame)

    {

       if(abs(*this) >= abs(another))

       {

           if(0 == sign)

           {

              BigInteger result;

              int nlunker = max(ndigit,another.ndigit);

 

              int residue = 0;

              for(int i = 0;i < nlunker;++i)

              {

                  int a1 = ((ndigit - 1 - i) >= 0) ? (modulus[ndigit - 1 - i] - '0') : 0;

                  int a2 = ((another.ndigit - 1 - i) >= 0) ? (another.modulus[another.ndigit - 1 - i] - '0') : 0;

                  int temp = residue + a1 - a2;

                  if(temp < 0)

                  {

                     result.modulus[nlunker - 1 - i] = ((temp + 10) % 10) + '0';

                     residue = -1;

                  }

                  else

                  {

                     result.modulus[nlunker - 1 - i] = (temp % 10) + '0';

                     residue = 0;

                  }

              }

              BigInteger newBigInteger;

              int nZero = 0;

              while('0' == result.modulus[nZero])

                  nZero++;

              newBigInteger.ndigit = nlunker - nZero;

              if(0 == newBigInteger.ndigit)

              {

                  newBigInteger.ndigit = 1;

                  newBigInteger.modulus[0] = '0';

                  newBigInteger.modulus[1] = '\0';

              }

              else

              {

                  memcpy(newBigInteger.modulus,result.modulus + nZero,newBigInteger.ndigit);

                  newBigInteger.modulus[newBigInteger.ndigit] = '\0';

              }

              newBigInteger.sign = 0;

 

              return newBigInteger;

           }

           else

           {

              BigInteger a1 = *this;

              BigInteger a2 = another;

              a1.sign = a2.sign = 0;

 

              return -(a1 - a2);

           }

       }

       else

       {

           if(0 == sign)

           {

              BigInteger a1 = *this;

              BigInteger a2 = another;

              return -(a2 - a1);

           }

           else

           {

              BigInteger a1 = *this;

              BigInteger a2 = another;

              a1.sign = a2.sign = 0;

 

              return a2 - a1;

           }

       }

    }

    else

    {

       if(0 == sign)

       {

           BigInteger a1 = *this;

           BigInteger a2 = another;

           a2.sign = 0;

           return a1 + a2;

       }

       else

       {

           BigInteger a1 = *this;

           BigInteger a2 = another;

           a1.sign = 0;

           return -(a1 + a2);

       }

    }

    BigInteger result;

 

    return result;

}

 

BigInteger& BigInteger::operator -= (const BigInteger& another)

{

    *this = *this - another;

    return *this;

}

 

BigInteger BigInteger::operator - ()

{

    BigInteger newBigInteger = *this;

    newBigInteger.sign = !newBigInteger.sign;

    return newBigInteger;

}

 

BigInteger BigInteger::operator * (const BigInteger& another)

{

    if((BigInteger("0") == *this) || (BigInteger("0") == another))

    {

       return BigInteger("0");

    }

 

    bool signSame = !(sign ^ another.sign);

    BigInteger result;

    int temp[MAXSIZE] = {0};

 

    BigInteger a1 = *this;

    BigInteger a2 = another;

 

    int i,j;

    for(i = 0;i < a1.ndigit;i++)

       for(j = 0;j < a2.ndigit;j++)

       {

           temp[i + j] += (a1.modulus[a1.ndigit - 1 - i] - '0') * (a2.modulus[a2.ndigit - 1 - j] - '0');

       }

       int residue = 0;

       for(i = 0;i < a1.ndigit + a2.ndigit - 1;i++)

       {

           temp[i + 1] += temp[i] / 10;

           temp[i] %= 10;

       }

       result.ndigit = (temp[a1.ndigit + a2.ndigit - 1] > 0) ? (a1.ndigit + a2.ndigit) : (a1.ndigit + a2.ndigit - 1);

 

       for(i = 0;i < result.ndigit;i++)

       {

           result.modulus[i] = temp[result.ndigit - 1 - i] + '0';

       }

       result.modulus[result.ndigit] = '\0';

       result.sign = signSame ? 0 : 1;

 

       return result;

}

 

BigInteger& BigInteger::operator *= (const BigInteger& another)

{

    *this = *this * another;

    return *this;

}

BigInteger BigInteger::operator / (const BigInteger& another)

{

    BigInteger result;

    if('0' == another.modulus[0])

    {

       memcpy(result.modulus,"error",6);

       return result;

    }

 

    bool signSame = !(sign ^ another.sign);

    if(abs(*this) < abs(another))

       return BigInteger("0");

    else if(abs(*this) == abs(another))

    {

       if(signSame)

           return BigInteger("1");

       else

           return BigInteger("-1");

    }

    else

    {

       BigInteger a1 = *this;

       BigInteger a2 = another;

       a1.sign = a2.sign = 0;

       BigInteger coe("-1");

       if(signSame)

           coe.sign = 0;

 

       if((a1.ndigit - a2.ndigit) <= 1)

       {

           int w = 0;

           while(a1 >= a2)

           {

              w++;

              a1 -= a2;

           }

           return (coe*BigInteger(w));

       }

       else

       {

           int w = a1.ndigit - a2.ndigit;

           BigInteger times;

           times.ndigit = w + 1;

           times.sign = 0;

           times.modulus[0] = '1';

           memset(times.modulus + 1,'0',w);

           times.modulus[times.ndigit] = '\0';

           if(a1 < (a2 * times))

           {

              times.ndigit = w;

              times.modulus[times.ndigit] = '\0';

           }

           return (coe*times + (coe*(a1 - a2 * times) / a2));

       }

    }

}

 

 

 

BigInteger& BigInteger::operator /= (const BigInteger& another)

{

    *this = *this / another;

    return *this;

}

BigInteger BigInteger::operator % (const BigInteger& another)

{

    BigInteger result;

    result = *this - (*this / another) * another;

    return result;

}

BigInteger& BigInteger::operator %= (const BigInteger& another)

{

    *this = *this % another;

    return *this;

}

BigInteger& BigInteger::operator ++ ()

{

    *this += BigInteger("1");

    return *this;

}

 

BigInteger& BigInteger::operator -- ()

{

    *this -= BigInteger("1");

    return *this;

}

 

/**

* 后递增(--),用参数int来代表是后递增

* 先调用拷贝构造函数拷贝当前对象,作为最后的返回值。然后直接增加当前对象,应

         该返回值,因为返回的是局部变量的拷贝。

@return 已经改变的对象的引用

*/ 

BigInteger BigInteger::operator ++(int)

    //cout<<"后递增++运算符的重载"<<endl; 

    BigInteger org(*this); 

    *this += BigInteger("1");

 

    return org

}

BigInteger BigInteger::operator --(int)

    //cout<<"后递增++运算符的重载"<<endl; 

    BigInteger org(*this); 

    *this -= BigInteger("1");

 

    return org

}

bool BigInteger::operator >= (const BigInteger& another)

{

    if(0 == sign && 1 == another.sign)

       return true;

    else if(1 == sign && 0 == another.sign)

       return false;

    else if(0 == sign && 0 == another.sign)

    {

       if(ndigit > another.ndigit)

           return true;

       else if(ndigit < another.ndigit)

           return false;

       else

       {

           int i = 0;

           while('\0' != modulus[i])

           {

              if(modulus[i] > another.modulus[i])

                  return true;

              else if(modulus[i] < another.modulus[i])

                  return false;

              i++;

           }

           return true;

       }

    }

    else

    {

       BigInteger a1 = *this;

       BigInteger a2 = another;

       return (-a2) >= (-a1);

    }

}

 

bool BigInteger::operator > (const BigInteger& another)

{

    if(*this <= another)

       return false;

    else

       return true;

}

 

bool BigInteger::operator <= (const BigInteger& another)

{

    if(0 == sign && 1 == another.sign)

       return false;

    else if(1 == sign && 0 == another.sign)

       return true;

    else if(0 == sign && 0 == another.sign)

    {

       if(ndigit > another.ndigit)

           return false;

       else if(ndigit < another.ndigit)

           return true;

       else

       {

           int i = 0;

           while('\0' != modulus[i])

           {

              if(modulus[i] > another.modulus[i])

                  return false;

              else if(modulus[i] < another.modulus[i])

                  return true;

              i++;

           }

           return true;

       }

    }

    else

    {

       BigInteger a1 = *this;

       BigInteger a2 = another;

       return (-a2) <= (-a1);

    }

}

 

bool BigInteger::operator < (const BigInteger& another)

{

    if(*this >= another)

       return false;

    else

       return true;

}

 

bool BigInteger::operator == (const BigInteger& another)

{

    if((*this >= another) && (*this <= another))

       return true;

    else

       return false;

}

bool BigInteger::operator != (const BigInteger& another)

{

    if((*this > another) || (*this < another))

       return true;

    else

       return false;

}

posted on 2009-11-04 08:18  龖龖  阅读(362)  评论(0编辑  收藏  举报

导航