//求模运算(调用除法)
int BigInt::Mod(_int64 X)
{
unsigned int M = 0;
this->Div(X,&M);
return M;
}
//比较两个大数的大小(只用于比较两个同号的大数)
bool BigInt::Comp(BigInt BI)
{
if(this->m_bSign == P) //先比较长度,再由高向低位依次比较
{
if(this->m_nLength > BI.m_nLength)
return true;
else if(this->m_nLength < BI.m_nLength)
return false;
else
{
int i= this->m_nLength;
while(this->m_nValue[i] == BI.m_nValue[i])
i--;
if(this->m_nValue[i] > BI.m_nValue[i])
return true;
else
return false;
}
}
else
{
if(this->m_nLength > BI.m_nLength)
return false;
else if(this->m_nLength < BI.m_nLength)
return true;
else
{
int i= this->m_nLength;
while(this->m_nValue[i] == BI.m_nValue[i])
i--;
if(this->m_nValue[i] > BI.m_nValue[i])
return false;
else
return true;
}
}
}
//加法
BigInt BigInt::Add(BigInt addend)
{
BigInt Sum;
//如果两数符号不同,调用减法
if(this->m_bSign != addend.m_bSign )
{
if(this->m_bSign == N)
{
this->m_bSign = P;
Sum = addend.Sub(*this);
this->m_bSign = N;
}
else
{
addend.m_bSign = P;
Sum = this->Sub(addend);
addend.m_bSign = N;
}
return Sum;
}
//符号相同
Sum.m_bSign = this->m_bSign ;
Sum.m_nLength = (this->m_nLength > addend.m_nLength) ? this->m_nLength : addend.m_nLength;
_int64 km = 0;
bool carry = 0; //进位标识
for(int i=0; i<Sum.m_nLength; i++)
{
km = this->m_nValue[i] + addend.m_nValue[i] + carry;
if(km > UPPERBOUND - 1) //有进位
{
carry = 1;
Sum.m_nValue[i] = km - UPPERBOUND;
}
else
{
carry = 0;
Sum.m_nValue[i] = km;
}
}
if(carry) //如果仍有进位,和的长度加一,并置一
{
Sum.m_nValue[i] = carry;
Sum.m_nLength ++;
if(Sum.m_nLength > MAXLENGTH)
cerr<<"overflow in add function!"<<endl;
}
return Sum;
}
//大数与32位无符号整型相加
void BigInt::Add(unsigned int addend)
{
int carry = 0;//进位标识
_int64 km = 0;
km = this->m_nValue[0] + addend;
if(km > UPPERBOUND - 1)//有进位
{
carry = 1;
this->m_nValue[0] = km - UPPERBOUND;
}
else
{
carry = 0;
this->m_nValue[0] = km;
return ;
}
//仍有进位,继续进行进位加
for(int i=1; i < this->m_nLength && carry; i++)
{
km = this->m_nValue[i] + carry;
if(km > UPPERBOUND - 1)
{
carry = 1;
this->m_nValue[0] = km - UPPERBOUND;
}
else
{
carry = 0;
this->m_nValue[0] = km;
}
}
if(carry)
{
this->m_nValue[i] = carry;
this->m_nLength ++;
if(this->m_nLength > MAXLENGTH)
cout<<"overflow!"<<endl;
}
}
BigInt BigInt::Sub(BigInt subtra)
{
BigInt Diff; //差
//若符号不同调用加法函数
if(this->m_bSign != subtra.m_bSign )
{
if(this->m_bSign == P)
{
subtra.m_bSign = P;
Diff = this->Add(subtra);
subtra.m_bSign = N;
}
else
{
subtra.m_bSign = N;
Diff = this->Add(subtra);
subtra.m_bSign = P;
}
return Diff;
}
if(this->Comp(subtra)) //被减数大于减数
{
if(this->m_bSign == P) //同为正号
{
Diff.m_nLength = this->m_nLength;
_int64 km;
int carry = 0;
for(int i=0;i<Diff.m_nLength; i++)
{
//预先借位减
km = UPPERBOUND + this->m_nValue[i] - subtra.m_nValue[i] - carry;
if(km >= UPPERBOUND) //不需要借位
{
carry = 0;
km = km - UPPERBOUND; //将借来的再减去
}
else
carry = 1;
Diff.m_nValue[i] = km;
}
}
else //同为负号,将被减数很减数都设置为正数,调用减法
{
this->m_bSign = P;
subtra.m_bSign = P;
Diff = subtra.Sub(*this); //减数减被减数
this->m_bSign = N;
subtra.m_bSign = N;
}
Diff.m_bSign = P;
}
else
{
if(this->m_bSign == P)
{
Diff = subtra.Sub(*this);
}
else
{
this->m_bSign = P;
subtra.m_bSign = P;
Diff = this->Sub(subtra);
this->m_bSign = N;
subtra.m_bSign = N;
}
Diff.m_bSign = N;
}
return Diff;
}
//大数乘法
BigInt BigInt::Mul(BigInt multiplier)
{
BigInt Product;
if(this->m_bSign == multiplier.m_bSign )
Product.m_bSign = P;
else
Product.m_bSign = N;
int i = multiplier.m_nLength - 1;
//由乘数的高位开始乘,先将部分积移位(乘10),然后和乘数第i位与被乘数的积相加
while(i>=0)
{
Product = Product.Mul(UPPERBOUND);
Product = Product.Add(Mul(multiplier.m_nValue[i]));
i--;
}
//积可达到的最长的位数
Product.m_nLength = this->m_nLength + multiplier.m_nLength;
if(Product.m_nValue[Product.m_nLength-1] == 0)
Product.m_nLength --;
return Product;
}
//大数与64位无符号整型相乘(实际达不到64位)
BigInt BigInt::Mul(_int64 multiplier)
{
BigInt Product;
_int64 km;
unsigned int carry = 0; //进位
Product.m_bSign = this->m_bSign;
for(int i=0; i<this->m_nLength; i++)
{
km = this->m_nValue[i] * multiplier + carry;
Product.m_nValue[i] = km % UPPERBOUND;
carry = km /UPPERBOUND;
}
if(carry)
{
Product.m_nValue[i] = carry;
Product.m_nLength = this->m_nLength + 1;
}
else
{
Product.m_nLength = this->m_nLength;
}
return Product;
}
//除法
BigInt BigInt::Div(unsigned int X,unsigned int *M )
{
BigInt result;
result.m_nLength = this->m_nLength;
result.m_bSign = this->m_bSign ;
_int64 km = 0;
//按竖式除法即可,km为上一位除得的余数
for(int i=this->m_nLength-1; i>=0; i--)
{
result.m_nValue[i] = (this->m_nValue[i]+km*UPPERBOUND)/X;
km = (this->m_nValue[i]+km*UPPERBOUND)%X;
}
if( (result.m_nLength != 1) && (result.m_nValue[result.m_nLength-1] == 0) )
result.m_nLength --;
if(this->m_bSign == N)
km = 10 - km;
if(M != NULL)
*M = km;
return result;
}
//幂的计算
BigInt BigInt::Power(BigInt index)
{
BigInt Product;
bool Sign = P;
int k = 0;
unsigned int M = 0;
char* str = new char[index.m_nLength*8*4];//用来存放指数的二进制序列
if(index.m_bSign == N)
{
cerr<<"指数不可为负!"<<endl;
return Product;
}
if(this->EqulZero()&&index.EqulZero())
{
cerr<<"底数和指数不可同时为零!"<<endl;
return Product;
}
if(index.Mod(2) == 1) //指数为奇数
Sign = this->m_bSign;
while( !index.EqulZero() )
{
index = index.Div(2,&M);
str[k] = '0' + M;
k++;
}
str[k] = '/0';
k--;
//下面是根据一个通用的求幂的快速算法
if(str[k--] == '1')
Product.Set(*this);
else
Product.Set(1);
for(int i= k; i>=0; i--)
{
Product = Product.Mul(Product);
if(str[i] == '1')
Product = Product.Mul(*this);
}
Product.m_bSign = Sign;
delete []str;
return Product;
}