|
[PHP]//---------------------------------------------------------------------------
#pragma hdrstop
#include "cmjint.h"
#include < stdlib.h >
#include < string.h >
#include < stdio.h >
//---------------------------------------------------------------------------
Cmjint::~Cmjint()
{ Punitint cdata=Ldata;
if(str)delete[] str;
while(cdata)
{Ldata=cdata->right;
delete cdata;
cdata=Ldata;
}
}
//---------------------------------------------------------------------------
const short Cmjint:: __B=8;
const typeint Cmjint:: __base=100000000;
const short Cmjint:: __h_base=10000;
const char Cmjint::_NUM[]={"0123456789"};
//---------------------------------------------------------------------------
Cmjint Cmjint: perator-()
{
Cmjint t1=*this;t1.plus=!t1.plus;return t1;
}
//---------------------------------------------------------------------------
ostream& operator <<(ostream &os,const Cmjint &lint)
{
if (!lint.plus)os<<'-';
Punitint da= lint.Ldata;
os.width(0);
os.fill(' ');
os.setf(ios::left);
os<<da->i;
da=da->right;
os.fill('0');
os.setf(ios::right);
while(da){
os.width(Cmjint::__B);
os<<da->i;
da=da->right;
}
return os;
}
//---------------------------------------------------------------------------
Cmjint operator+(const typeint &tthis,const Cmjint &sthis)
{return(Cmjint(tthis)+(sthis));
}
Cmjint operator-(const typeint &tthis,const Cmjint &sthis)
{return(Cmjint(tthis)-(sthis));
}
Cmjint operator*(const typeint &tthis,const Cmjint &sthis)
{return(Cmjint(tthis)*(sthis));
}
Cmjint operator/(const typeint &tthis,const Cmjint &sthis)
{return(Cmjint(tthis)/(sthis));
}
Cmjint operator%(const typeint &tthis,const Cmjint &sthis)
{ return(Cmjint(tthis)%(sthis));
}
//~~~~~~~~
Cmjint operator+(const char * tthis,const Cmjint &sthis)
{return(Cmjint(tthis)+(sthis));
}
Cmjint operator-(const char * tthis,const Cmjint &sthis)
{return(Cmjint(tthis)-(sthis));
}
Cmjint operator*(const char * tthis,const Cmjint &sthis)
{return(Cmjint(tthis)*(sthis));
}
Cmjint operator/(const char * tthis,const Cmjint &sthis)
{return(Cmjint(tthis)/(sthis));
}
Cmjint operator%(const char * tthis,const Cmjint &sthis)
{return(Cmjint(tthis)%(sthis));
}
//---------------------------------------------------------------------------
inline void Cmjint::Allocate(Punitint & pnew,emLR linkLR)
{ pnew=new Unitint;
if(linkLR==emLeft)
{Ldata->left=pnew;
pnew->right=Ldata;
Ldata=pnew;
}
if(linkLR==emRight)
{Rdata->right=pnew;
pnew->left=Rdata;
Rdata=pnew;
}
++bit;
}
//---------------------------------------------------------------------------
Cmjint& Cmjint: perator+=( const Cmjint & sthis)
{
if(plus&&!sthis.plus)
{const_cast<Cmjint&>(sthis).plus=1;
*this-=sthis;
const_cast<Cmjint&>(sthis).plus=0;
return *this;
}
if(!plus&&sthis.plus)
{plus=1;
*this-=sthis;
plus=!plus;
return *this;
}
Punitint tdata=data;
Punitint sdata=sthis.data;
short flag(0);
while(sdata||flag)
{
if(tdata==NULL)
{
Allocate(tdata,emLeft);
if(sdata) tdata->i=sdata->i;
}else
if(sdata)tdata->i+=sdata->i;
if(flag) tdata->i+=flag;
flag=tdata->i/__base;
tdata->i%=__base;
tdata=tdata->left;
if(sdata)sdata=sdata->left;
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cmjint Cmjint: perator+( const Cmjint& sthis) const
{ Cmjint tthis(*this);
return tthis+=sthis;
}
//---------------------------------------------------------------------------
Cmjint &Cmjint: perator=( const typeint& i)
{ Clear();
// if(i<0)plus=0;
// data->i=i;
// if(!plus)data->i=-data->i;
char str[16];
itoa(i,str,10);
*this=str;
return *this;
}
//...........
bool _checkNum(const char * str)
{
const char * s=str;
while(*s!='\0')
{if( (*s<'0'||*s>'9')&&*s!='-')return 0;
--s;
}
return 1;
} //
Cmjint &Cmjint: perator=(const char * str)
{
// if(!_checkNum(str)) throw;
Clear();
char *ss;
if(str[0]=='-')
{plus=0;
ss=new char[strlen(str)];
strcpy(ss,str+1);
}else
{ ss=new char[strlen(str)+1];
strcpy(ss,str);
}
short len=strlen(ss);
Punitint t=data;
char c;
while(len>0)
{if(!t)Allocate(t,emLeft);
c=ss[len];
ss[len]='\0';
if(len>__B)t->i=atol(ss+len-__B);
else t->i=atol(ss);
ss[len]=c;
len-=__B;
t=t->left;
}
delete[] ss;
return *this;
}
//...........
Cmjint &Cmjint: perator=( const Cmjint & sthis)
{if(this==&sthis)return *this;
Clear();
Punitint s=sthis.data;
Punitint t=data;
while(s){
if(!t)Allocate(t,emLeft);
t->i=s->i;
t=t->left;
s=s->left;
}
plus=sthis.plus;
return *this;
}
//---------------------------------------------------------------------------
Cmjint& Cmjint: perator-=( const Cmjint & sthis)
{
if(plus&&!sthis.plus)//x-(-x)
{const_cast<Cmjint&>(sthis).plus=1;
*this+=sthis;
const_cast<Cmjint&>(sthis).plus=0;
return *this;
}
if(!plus&&sthis.plus) //-x-x
{
plus=1;
*this+=sthis;
plus=0;
return *this;
}
bool change=0;
if(plus&&sthis.plus)
{ if(*this>=sthis)plus=1; //xx-x
else {plus=0;change=1;} //x-xx
}else
{
plus=1;
const_cast<Cmjint&>(sthis).plus=1;
if(*this>=sthis)plus=0; //-xx-(-x)
else {plus=1;change=1;} //-x-(-xx)
const_cast<Cmjint&>(sthis).plus=0;
}
Punitint tdata=data;
Punitint sdata=sthis.data;
short flag(0);
if(change)
while(sdata||flag){
if(flag) {--sdata->i ; flag=0; }
if(tdata) tdata->i=sdata->i-tdata->i;
else {Allocate(tdata,emLeft);tdata->i=sdata->i; }
if(tdata->i<0){tdata->i+=__base;flag=1;}
if(tdata)tdata=tdata->left;
sdata=sdata->left;
}
else
while(tdata||flag){
if(flag) {--tdata->i; flag=0; }
if(sdata) tdata->i-=sdata->i ;
if(tdata->i<0){tdata->i+=__base;flag=1;}
if(sdata)sdata=sdata->left;
tdata=tdata->left;
}
Deletezero();
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cmjint Cmjint: perator-(const Cmjint & sthis)const
{ Cmjint tthis(*this);
return (tthis-=sthis);
}
//---------------------------------------------------------------------------
bool Cmjint: perator>( const Cmjint & sthis)const
{
if(plus>sthis.plus) return 1;
if(plus<sthis.plus) return 0;
if(bit>sthis.bit) return 1;
if(bit<sthis.bit) return 0;
//if(Ldata->i>sthis.Ldata->i)return plus;
Punitint t=Ldata;
Punitint s=sthis.Ldata;
while(t)
{if(t->i>s->i)return plus;
if(t->i<s->i)return !plus;
t=t->right;
s=s->right;
}
return 0;
}
//~~~~~~~~~~~
bool Cmjint: perator==( const Cmjint & sthis)const
{
if(plus!=sthis.plus) return 0;
if(bit!=sthis.bit) return 0;
Punitint t=Ldata;
Punitint s=sthis.Ldata;
while(t)
{if(t->i!=s->i)return 0;
t=t->right;
s=s->right;
}
return 1;
}
//~~~~~~~~~~~~~~~~~~~~~~
bool Cmjint::operator<( const Cmjint & sthis)const
{return sthis>*this;
}
//~~~~~~~~~~~
bool Cmjint::operator>=( const Cmjint & sthis)const
{return !(*this<sthis);
}
//~~~~~~~~~~~
bool Cmjint::operator<=( const Cmjint & sthis)const
{return !(*this>sthis) ;
}
//~~~~~~~~~~~
bool Cmjint::operator!=( const Cmjint & sthis)const
{return !(*this==sthis);
}
//---------------------------------------------------------------------------
Cmjint Cmjint::operator++(int)
{Cmjint sthis(*this);
*this+=Cmjint(1);
return(sthis);
}
Cmjint Cmjint::operator--(int)
{
Cmjint sthis(*this);
*this-=Cmjint(1);
return(sthis);
}
Cmjint& Cmjint::operator++()
{return(*this+=Cmjint(1));
}
Cmjint& Cmjint::operator--()
{return(*this-=Cmjint(1));
}
//---------------------------------------------------------------------------
void Cmjint: rint()
{ cout<<*this;
}
//~~~~~~~~~~~
void Cmjint: eletezero()
{ Punitint t=Ldata;
while(bit>1)
{
if(t->i==0){t=t->right;delete t->left;Ldata=t;bit--;Ldata->left=NULL;}
else break;
}
}
//~~~~~~~~~~~
void Cmjint::Clear()
{ //reset data to 0;
Punitint cdata=Ldata;
while(cdata)
{Ldata=cdata->right;
delete cdata;
cdata=Ldata;
}
data=new Unitint;
Ldata=data;
Rdata=data;
bit=1;
plus=1;
}
//---------------------------------------------------------------------------
void Cmjint::_Mul8(Cmjint &dest,const Cmjint &sthis,const typeint &s)
{
Punitint tdata=dest.data;
Punitint sdata=sthis.data;
register typeint flag(0);
while(sdata||flag)
{
if(!sdata)
{ if(!tdata)
dest.Allocate(tdata,emLeft);
tdata->i=flag; //shxx slxx
return; //hhxx llxx
}
if(!tdata)dest.Allocate(tdata,emLeft);
register typeint temp,sh,sl,p1;
short hh=s/__h_base;
short ll=s%__h_base;
//temp=0;
sh=sdata->i/__h_base;
sl=sdata->i%__h_base;
temp=sl*ll;
p1=ll*sh;
sl*=hh;
sh*=hh;
temp+=flag+(p1%__h_base)*__h_base+(sl%__h_base)*__h_base;
tdata->i=temp%__base;
flag=sh+p1/__h_base+sl/__h_base+temp/__base;
tdata=tdata->left;
sdata=sdata->left;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~
void Cmjint::_moveleft_onebit(Cmjint & sthis, short n)
{
while(n-->0)
sthis.Allocate(sthis.data,emRight);
}
//~~~~~~~~~~~~~~~~
Cmjint& Cmjint::operator*=( const Cmjint & sthis)
{
bool p=(plus==sthis.plus);
Cmjint t2;
short xx=-1;
Punitint tdata=data;
typeint ss ;
while(tdata)
{ Cmjint t1;
ss=tdata->i;
_Mul8(t1,sthis,ss);
_moveleft_onebit(t1,++xx);
t2+=t1;
tdata=tdata->left;
}
t2.plus=p;
*this=t2;
return *this;
}
//~~~~~~~~~~~
Cmjint Cmjint::operator*( const Cmjint & sthis)const
{
bool p=(plus==sthis.plus);
Cmjint t2;
short xx=-1;
Punitint tdata=data;
typeint ss ;
while(tdata)
{Cmjint t1;
ss=tdata->i;
_Mul8(t1,sthis,ss);
_moveleft_onebit(t1,++xx);
t2+=t1;
tdata=tdata->left;
}
t2.plus=p;
return t2;
}
//---------------------------------------------------------------------------
int Cmjint: ength()const
{
int x=(this->bit-1)*__B;
typeint i=this->Ldata->i;
while(i>0)
{i/=10; x++;}
return x;
}
//---------------------------------------------------------------------------
typeint _pow( short n)
{
typeint x=1;while(n--)x*=10;
return x;
}
//~~~~~~~~~~~~~~~~~~~~~~~
bool Cmjint::_getsfromhead(const Cmjint&sthis,char *str,short n)
{ Punitint tdata=sthis.Ldata;
char *s=str;
itoa(tdata->i,s,10);
short t1=strlen(s);
if(n<t1){ *(s+n)='\0';return 1;}
tdata=tdata->right;
if(!tdata)return 0;
n-=t1;s+=t1;
while(n>=__B){
itoa(tdata->i,s,10);
n-=__B;
s+=__B;
tdata=tdata->right;
if(!tdata)return 0;
}
if(n>0)
itoa(tdata->i/_pow(__B-n),s,10);
return 1;
}
//~~~~~~~~~~~~~~~~~~~~~~~
void Cmjint::_getnumfromright(const Cmjint & sthis,const short& bit,short &num)
{
short b=(bit-1)/__B;
short n=bit%__B;
Punitint pu=sthis.data;
while(--b>=0)
pu=pu->left;
if(n==0){num=pu->i/10000000;return ; } //__B
if(n==1){num=pu->i%10; return; }
typeint x=1; while(--n)x*=10;
num= pu->i/x%10;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cmjint& Cmjint::operator%=( const Cmjint & sthis)
{
bool p=(plus==sthis.plus);
bool pp=sthis.plus;
const_cast<Cmjint &>(sthis).plus=1;
int n1=this->Length();
int n2=n1-sthis.Length();
int n=0;
Cmjint t1;
char *str=new char[n1+1];
_getsfromhead(*this,str,n1-n2);
if(Cmjint(str)>=sthis)t1=str;else{_getsfromhead(*this,str,n1-n2+1); t1=str; --n2;}
short num;
short x;
while(n2>=0)
{ x=0;
while(t1>=sthis){ ++x; t1-=sthis ; }
str[n++]=_NUM[x];
_getnumfromright(*this,n2--,num);
if(n2<0)break;
t1*=10;
t1+=num;
}
*this=t1;
delete []str;
this->plus=p;
const_cast<Cmjint &>(sthis).plus=pp;
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cmjint Cmjint::operator%( const Cmjint & sthis)const
{
Cmjint tthis(*this);
return (tthis%=sthis);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cmjint&Cmjint::operator/=( const Cmjint & sthis)
{
bool p=(plus==sthis.plus);
bool pp=sthis.plus;
const_cast<Cmjint &>(sthis).plus=1;
int n1=this->Length();
int n2=n1-sthis.Length();
int n=0;
Cmjint t1;
char *str=new char[n1+1];
_getsfromhead(*this,str,n1-n2);
if(Cmjint(str)>=sthis)t1=str;else{_getsfromhead(*this,str,n1-n2+1); t1=str; --n2;}
short num;
short x;
while(n2>=0)
{ x=0;
while(t1>=sthis){ ++x; t1-=sthis ; }
str[n++]=_NUM[x];
_getnumfromright(*this,n2--,num);
if(n2<0)break;
t1*=10;
t1+=num;
}
str[n]='\0';
*this=str;
delete []str;
this->plus=p;
const_cast<Cmjint &>(sthis).plus=pp;
return *this;
}
//~~~~~~~~~~
Cmjint Cmjint::operator/( const Cmjint & sthis)const
{
Cmjint tthis(*this);
return (tthis/=sthis);
}
//----------------------------------------------------------------------
char * Cmjint::c_str()
{
if(str)delete []str;
str=new char[bit*__B+2];
Punitint da= Ldata;
char *s=str;
if(!plus){s[0]='-';++s;}
sprintf(s,"%ld",da->i);
da=da->right;
s+=__B-bit*__B+Length();
while(da){
sprintf(s,"%#08ld",da->i);
s+=__B;
da=da->right;
}
return str;
}
//----------------------------------------------------------------------
[/PHP] |
|