您的位置:首页 > 编程语言 > C语言/C++

大整数处理类(cpp文件)

2009-11-04 08:18 253 查看
///////////////////////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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐