///////////////////////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;
}