// bigint.cpp: implementation of the bigint class.
//定义一个超高精度的类bigint的实现算法代码,用以实现超过20位有效数字整型数值
//的运算,并具有兼容已有整型数据int的能力,能与int数据混合运算。
//////////////////////////////////////////////////////////////////////
#include<string.h>
#include "bigint.h"
#include <stdlib.h>
#include <math.h>
#define z1 "0"
#define z2 "00"
#define z3 "000"
#define z4 "0000"
#define R 10000
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//空初始化
bigint::bigint()
{
sign=1;
arr_n=1;
sl=new long[arr_n];
sl[0] =0;
soure=new char[8];
soure="0";
}
//把数值字符串设置值给bigint类对象
void bigint::setval(const char * s)
{
char SIGN,temp[5];
int len,i,j=4,k=0;
SIGN=s[0];
switch(SIGN)
{
case '-':
case '+':
{
if(SIGN=='-')sign=-1; //判断正负
if(SIGN=='+')sign=+1;
len=strlen(s); //把数值字符串保存到soure中,包括'\0'和符号位
soure=new char[len+1];
strcpy(soure,s);
for(int n=0;n<=len;n++)soure[n]=soure[n+1]; //去掉符号位
len=strlen(soure);
if (len%4==0) arr_n=(int)len/4;
else arr_n=(int)(len/4+1);
sl=new long[arr_n];
for(i=len;i>=0;i--) //把数值串赋值给数组,每四个数值字符转换成一个长整数
{
temp[j]=soure[i];
if(i==0&&j)
for(int q=0;q<j;q++)temp[q]='0';
if(j==0||i==0)
{
temp[4]='\0';
sl[k]=atol(temp);
j=4;k++;
}
j--;
}
break;
}
default:
{
sign=+1;
len=strlen(s);
soure=new char[len+1];
strcpy(soure,s);
if (len%4==0) arr_n=(int)len/4;
else arr_n=(int)(len/4+1);
sl=new long[arr_n];
for(i=len;i>=0;i--) //把数值串赋值给数组
{
temp[j]=soure[i];
if(i==0&&j)
for(int q=0;q<j;q++)temp[q]='0';
if(j==0||i==0)
{
temp[4]='\0';
sl[k]=atol(temp);
j=4;k++;
}
j--;
}
break;
}
}
}
//拷贝构造函数
bigint::bigint(const bigint & a)
{
int i;
sign=a.sign;
int n=strlen(a.soure);
soure=new char[n+1];
for(i=0;i<=n;i++)
soure[i]=a.soure[i];
arr_n=a.arr_n;
sl=new long[arr_n];
for(i=0; i<arr_n; i++)
sl[i]=a.sl[i];
}
//获取值,以字符串方式取出
char * bigint::getval ()
{
char * temp,*e="-";
if(sign==-1)
{
temp=new char[strlen(soure)+2];
strcpy(temp,e);
strcat(temp,soure);
}
else
{
temp=new char[strlen(soure)+1];
strcpy(temp,soure);
}
return temp;
}
//以数值字符串进行初始化
bigint::bigint(const char * s)
{
setval(s);
}
//大于比较:真值为ture;假值为flase
bool bigint::operator >(const bigint &num)
{
if(sign >num.sign ) return true;
if (sign==1&&num.sign==1)
{
if (strlen(soure) >strlen(num.soure) ) return true;
if ((strlen(soure) ==strlen(num.soure))&&(strcmp(soure ,num.soure )>0)) return true;
}
if (sign==-1&&num.sign==-1)
{
if (strlen(soure) <strlen(num.soure) ) return true;
if ((strlen(soure) ==strlen(num.soure))&&(strcmp(soure ,num.soure )<0)) return true;
}
return false;
}
//等于比较:真值为ture;假值为flase
bool bigint::operator ==(const bigint &num)
{
if ((sign==num.sign)&&(strcmp(soure ,num.soure )==0)) return true;
else return false;
}
//不等于比较:真值为ture;假值为flase
bool bigint::operator !=(const bigint &num)
{
if ((sign!=num.sign)||(strcmp(soure ,num.soure )!=0)) return true;
else return false;
}
//大于等于比较:真值为ture;假值为flase
bool bigint::operator >=(const bigint &num)
{
if(*this>num||*this==num)return true;
else return false;
}
//小于比较:真值为ture;假值为flase
bool bigint::operator <(const bigint &num)
{
if(!(*this>=num))return true;
else return false;
}
//小于等于比较:真值为ture;假值为flase
bool bigint::operator <=(const bigint &num)
{
if(!(*this>num)) return true;
else return false;
}
//进位、借位调整器
void regulator(bigint *num)
{
int i;
for(i=0;i<num->arr_n ;i++)
{
if(num->sl[i]>=R) //进位调整
{
num->sl[i+1]+=num->sl[i]/R;
num->sl[i]%=R;
}
if(num->sl[i]<0) //借位调整
{
num->sl[i+1]=num->sl[i+1]-1;
num->sl[i]+=R;
}
}
}
void regulator_sign(bigint *num) //符号调整
{
int flag=1,i;
if(num->sl[num->arr_n-1]<0)flag=-1;
num->sign=flag*num->sign;
for(i=0;i<num->arr_n ;i++)num->sl[i]=flag*num->sl[i];
}
//整理数组值到串soure
void sltostr(bigint *num)
{
int i;
char * n_temp,*c_temp;
n_temp=new char[5];
c_temp=new char[5];
num->soure =new char[num->arr_n *4+4]; //为什么要再加上4?
num->soure[0]='\0';
i=num->arr_n-1;
if(num->sl[i]) //处理最高位
{
ltoa(num->sl[i],n_temp,10) ;
strcpy(num->soure ,n_temp);
}
int l=0;
while(i) //处理高位后的各位数
{
i--;
ltoa(num->sl[i],n_temp,10);
l=4-strlen(n_temp);
if(l>0)
{
if(l==1)strcpy(c_temp,z1);
if(l==2)strcpy(c_temp,z2);
if(l==3)strcpy(c_temp,z3);
if(l==4)strcpy(c_temp,z4);
strcat(num->soure,c_temp);
}
strcat(num->soure,n_temp);
}
int len;
while(num->soure[0]=='0')//去除无效0的处理
{
len=strlen(num->soure );
for(i=0;i<len; i++)
num->soure [i]=num->soure [i+1];
}
if(num->soure[0]=='\0')strcpy(num->soure,"0");
}
//与常规整数的加运算
bigint bigint::operator +(int num)
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
bigint temp(s);
char * ss;
ss=new char[31];
itoa(num,ss,10);
bigint AA(ss);
bigint temp0;
temp0=temp+AA;
return temp0;
}
//与常规整数的减运算
bigint bigint::operator -(int num)
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
bigint temp(s); //取左操作数
char * ss;
ss=new char[31];
itoa(num,ss,10);
bigint A(ss); //取右操作数
bigint temp0;
temp0=temp-A;
return temp0;
}
//加运算
bigint bigint::operator +(const bigint &num)
{
int i;
bigint temp;
temp.arr_n =arr_n>num.arr_n ?arr_n:num.arr_n ;
if((arr_n==num.arr_n )&&abs((sl[arr_n-1]*sign+num.sl[num.arr_n-1 ]*num.sign ))>=R) ++temp.arr_n ;
temp.sl=new long[temp.arr_n ];
for(i=0;i<temp.arr_n ;i++)temp.sl[i]=0;
for(i=0;i<temp.arr_n ;i++)
{
if((i>=arr_n)&&(num.arr_n>arr_n ))temp.sl[i]=num.sl[i]*num.sign ;
if((i>=num.arr_n )&&(arr_n >num.arr_n))temp.sl[i]=sl[i]*sign;
if((i<arr_n)&&(i< num.arr_n ))temp.sl[i]=sl[i]*sign+num.sl[i]*num.sign ;
}
regulator_sign(&temp); //必须先做符号调整让temp中sl的最高位符号为正,再进位、借位调整
regulator(&temp); //进位借位调整完后sl中的数都是正数了
sltostr(&temp);
return temp;
}
//求相反数
bigint bigint:: operator -()
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
bigint temp(s);
temp.sign *=-1;
return temp;
}
//减运算
bigint bigint::operator -(const bigint &num)
{
bigint temp,A;
A=num ;
A.sign *=-1 ;
temp=*this+A;
return temp;
}
//与常规整数的乘运算
bigint bigint::operator *(int num)
{
int i,j;
char * ss;
ss=new char [31];
itoa(num ,ss,10);
bigint temp,a(ss);
temp.arr_n =arr_n+a.arr_n ;
temp.sign =sign*a.sign ;
temp.sl=new long[temp.arr_n ];
for(i=0;i<temp.arr_n ;i++)temp.sl[i]=0;
for(i=0;i<arr_n;i++)
{
for(j=0;j<a.arr_n ;j++)
{
temp.sl[i+j]+=sl[i]*a.sl[j];
}
regulator(&temp);
}
sltostr(&temp);
return temp;
}
//乘运算
bigint bigint::operator *(const bigint &num)
{
int i,j;
bigint temp;
temp.sign =sign*num.sign ;
temp.arr_n =arr_n+num.arr_n ;
temp.sl=new long[temp.arr_n ];
for(i=0;i<temp.arr_n ;i++)temp.sl[i]=0;
for(i=0;i<arr_n;i++)
{
for(j=0;j<num.arr_n ;j++)
{
temp.sl[i+j]+=sl[i]*num.sl[j];
}
regulator(&temp); //此处不用符号调整,因为加数与被加数sl中对应各位都是正数
}
- 1
- 2
前往页