<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
#include
<
stdio.h
>
#include < math.h >
#include < iostream >
using namespace std;
class decnum
{
frienddecnumpow( const decnum & x, int n);
frienddecnumroot( const decnum & x, int n);
frienddecnumdiv( const decnum & x, const decnum & y,decnum & r);
frienddecnumabs( const decnum & x);
friend bool operator == ( const decnum & x, const decnum & y);
friend bool operator != ( const decnum & x, const decnum & y);
friend bool operator > ( const decnum & x, const decnum & y);
friend bool operator < ( const decnum & x, const decnum & y);
friend bool operator >= ( const decnum & x, const decnum & y);
friend bool operator <= ( const decnum & x, const decnum & y);
friendostream & operator << (ostream & os, const decnum & x);
public :
decnum():cap( 0 ),num( 0 ),sign( 0 ),val(NULL){}
decnum( const char * v, int n)
{
int i,j,k;
val = new char [n];
if (v[ 0 ] == ' - ' )
{
sign = 1 ;
v ++ ;
n -- ;
}
else
{
sign = 0 ;
if (v[ 0 ] == ' + ' )
v ++ ;
}
for (i = 0 ;i < n && v[i] == ' 0 ' ;i ++ );
for (j = 0 ,k = n - 1 ;k >= i; -- k, ++ j)
{
if (v[k] >= ' 0 ' && v[k] <= ' 9 ' )
{
val[j] = v[k] - ' 0 ' ;
}
else
break ;
}
num = j;
cap = n;
}
decnum( const decnum & x)
{
val = new char [x.num];
memcpy(val,x.val,x.num);
sign = x.sign;
num = x.num;
cap = x.num;
}
decnum( int x)
{
if (x == 0 )
{
cap = num = 0 ;
val = NULL;
return ;
}
if (x < 0 )
{
sign = 1 ;
x = - x;
}
else
sign = 0 ;
char temp[ 20 ];
sprintf(temp, " %d " ,x);
int n = strlen(temp);
num = cap = n;
val = new char [n];
for ( int i = 0 ;i < n;i ++ )
val[i] = temp[n - 1 - i] - ' 0 ' ;
}
decnum( long long x)
{
if (x == 0 )
{
cap = num = 0 ;
val = NULL;
return ;
}
if (x < 0 )
{
sign = 1 ;
x = - x;
}
else
sign = 0 ;
char temp[ 20 ];
sprintf(temp, " %lld " ,x);
int n = strlen(temp);
num = cap = n;
val = new char [n];
for ( int i = 0 ;i < n;i ++ )
val[i] = temp[n - 1 - i] - ' 0 ' ;
}
~ decnum(){delete[]val;}
int size() const { return num;}
decnum & operator = ( const decnum & x)
{
if ( this != & x)
{
if (cap < x.num)
{
delete[]val;
val = new char [x.num];
cap = x.num;
}
memcpy(val,x.val,x.num);
num = x.num;
sign = x.sign;
}
return * this ;
}
decnum & operator = ( int x)
{
* this = decnum(x);
return * this ;
}
decnum & operator = ( long long x)
{
* this = decnum(x);
return * this ;
}
decnum & abs()
{
sign = 0 ;
return * this ;
}
decnum & operator += ( const decnum & x);
decnum & operator -= ( const decnum & x);
decnum & operator *= ( const decnum & x);
decnum & operator /= ( const decnum & x);
decnum & operator %= ( const decnum & x);
decnum operator + ( const decnum & x) const ;
decnum operator - ( const decnum & x) const ;
decnum operator * ( const decnum & x) const ;
decnum operator / ( const decnum & x) const ;
decnum operator % ( const decnum & x) const ;
bool ispow( int n,decnum & r) const ;
bool ispow() const ;
private :
int cap;
int num;
int sign;
char * val;
private :
char root_1( int n);
decnum & absadd( const decnum & x);
decnum & abssub( const decnum & x);
bool absge( const decnum & x);
};
#include < math.h >
#include < iostream >
using namespace std;
class decnum
{
frienddecnumpow( const decnum & x, int n);
frienddecnumroot( const decnum & x, int n);
frienddecnumdiv( const decnum & x, const decnum & y,decnum & r);
frienddecnumabs( const decnum & x);
friend bool operator == ( const decnum & x, const decnum & y);
friend bool operator != ( const decnum & x, const decnum & y);
friend bool operator > ( const decnum & x, const decnum & y);
friend bool operator < ( const decnum & x, const decnum & y);
friend bool operator >= ( const decnum & x, const decnum & y);
friend bool operator <= ( const decnum & x, const decnum & y);
friendostream & operator << (ostream & os, const decnum & x);
public :
decnum():cap( 0 ),num( 0 ),sign( 0 ),val(NULL){}
decnum( const char * v, int n)
{
int i,j,k;
val = new char [n];
if (v[ 0 ] == ' - ' )
{
sign = 1 ;
v ++ ;
n -- ;
}
else
{
sign = 0 ;
if (v[ 0 ] == ' + ' )
v ++ ;
}
for (i = 0 ;i < n && v[i] == ' 0 ' ;i ++ );
for (j = 0 ,k = n - 1 ;k >= i; -- k, ++ j)
{
if (v[k] >= ' 0 ' && v[k] <= ' 9 ' )
{
val[j] = v[k] - ' 0 ' ;
}
else
break ;
}
num = j;
cap = n;
}
decnum( const decnum & x)
{
val = new char [x.num];
memcpy(val,x.val,x.num);
sign = x.sign;
num = x.num;
cap = x.num;
}
decnum( int x)
{
if (x == 0 )
{
cap = num = 0 ;
val = NULL;
return ;
}
if (x < 0 )
{
sign = 1 ;
x = - x;
}
else
sign = 0 ;
char temp[ 20 ];
sprintf(temp, " %d " ,x);
int n = strlen(temp);
num = cap = n;
val = new char [n];
for ( int i = 0 ;i < n;i ++ )
val[i] = temp[n - 1 - i] - ' 0 ' ;
}
decnum( long long x)
{
if (x == 0 )
{
cap = num = 0 ;
val = NULL;
return ;
}
if (x < 0 )
{
sign = 1 ;
x = - x;
}
else
sign = 0 ;
char temp[ 20 ];
sprintf(temp, " %lld " ,x);
int n = strlen(temp);
num = cap = n;
val = new char [n];
for ( int i = 0 ;i < n;i ++ )
val[i] = temp[n - 1 - i] - ' 0 ' ;
}
~ decnum(){delete[]val;}
int size() const { return num;}
decnum & operator = ( const decnum & x)
{
if ( this != & x)
{
if (cap < x.num)
{
delete[]val;
val = new char [x.num];
cap = x.num;
}
memcpy(val,x.val,x.num);
num = x.num;
sign = x.sign;
}
return * this ;
}
decnum & operator = ( int x)
{
* this = decnum(x);
return * this ;
}
decnum & operator = ( long long x)
{
* this = decnum(x);
return * this ;
}
decnum & abs()
{
sign = 0 ;
return * this ;
}
decnum & operator += ( const decnum & x);
decnum & operator -= ( const decnum & x);
decnum & operator *= ( const decnum & x);
decnum & operator /= ( const decnum & x);
decnum & operator %= ( const decnum & x);
decnum operator + ( const decnum & x) const ;
decnum operator - ( const decnum & x) const ;
decnum operator * ( const decnum & x) const ;
decnum operator / ( const decnum & x) const ;
decnum operator % ( const decnum & x) const ;
bool ispow( int n,decnum & r) const ;
bool ispow() const ;
private :
int cap;
int num;
int sign;
char * val;
private :
char root_1( int n);
decnum & absadd( const decnum & x);
decnum & abssub( const decnum & x);
bool absge( const decnum & x);
};
实现代码
![ContractedBlock.gif](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"decnum.h"
decnum&decnum::absadd(constdecnum&x)
{
inti,max;
charcarry=0,ch;
if(x.num==0)return*this;
if(num<x.num)
max=x.num+1;
else
max=num+1;
if(max>cap)
{
cap=max;
char*newval=newchar[cap];
memcpy(newval,val,num);
memset(newval+num,0,cap-num);
delete[]val;
val=newval;
}
else
{
memset(val+num,0,max-num);
}
num=max-1;
for(i=0;i<x.num;i++)
{
ch=val[i]+x.val[i]+carry;
if(ch>9)
{
carry=1;
val[i]=ch-10;
}
else
{
carry=0;
val[i]=ch;
}
}
for(;i<=num&&carry==1;i++)
{
ch=val[i]+1;
if(ch>9)
{
carry=1;
val[i]=ch-10;
}
else
{
carry=0;
val[i]=ch;
}
}
if(i>num)num=i;
return*this;
}
decnum&decnum::abssub(constdecnum&x)
{
if(x.num==0)return*this;
inti;
charcarry=0,ch;
for(i=0;i<x.num;i++)
{
ch=val[i]-x.val[i]-carry;
if(ch<0)
{
carry=1;
val[i]=ch+10;
}
else
{
carry=0;
val[i]=ch;
}
}
for(;i<num&&carry==1;i++)
{
ch=val[i]-1;
if(ch<0)
{
carry=1;
val[i]=ch+10;
}
else
{
carry=0;
val[i]=ch;
}
}
for(i=num;i>0&&val[i-1]==0;i--);
num=i;
return*this;
}
booldecnum::absge(constdecnum&x)
{
if(num>x.num)returntrue;
if(num<x.num)returnfalse;
for(inti=num-1;i>=0;i--)
{
if(val[i]>x.val[i])
returntrue;
elseif(val[i]<x.val[i])
returnfalse;
}
returntrue;
}
decnum&decnum::operator+=(constdecnum&x)
{
if(x.sign==sign)
returnabsadd(x);
elseif(absge(x))
returnabssub(x);
else
{
decnumtmp(*this);
*this=x;
returnabssub(tmp);
}
}
decnum&decnum::operator-=(constdecnum&x)
{
if(x.sign!=sign)
returnabsadd(x);
elseif(absge(x))
returnabssub(x);
else
{
decnumtmp(*this);
*this=x;
returnabssub(tmp);
}
}
decnum&decnum::operator*=(constdecnum&x)
{
if(num==0)return*this;
if(x.num==0)
{
num=0;
return*this;
}
if(sign==x.sign)
sign=0;
else
sign=1;
intmul,i,n,newcap,max;
charch,carry;
char*newval=newchar[num+x.num];
newcap=num+x.num;
memset(newval,0,num+x.num);
decnuma,b;
char*ptr;
for(i=0;i<num&&val[i]==0;i++);
intna=i;
a.val=val+i;
a.num=num-i;
for(i=0;i<num&&x.val[i]==0;i++);
intnb=i;
b.val=x.val+i;
b.num=x.num-i;
ptr=newval+na+nb;
for(n=0;n<=a.num+b.num-2;n++)
{
mul=0;
if(n>b.num-1)
i=n-b.num+1;
else
i=0;
max=n<a.num-1?n:a.num-1;
for(;i<=max;i++)
mul+=a.val[i]*b.val[n-i];
carry=0;
for(i=n;mul>0||carry>0;mul/=10,i++)
{
ch=ptr[i]+mul%10+carry;
if(ch>9)
{
carry=1;
ptr[i]=ch-10;
}
else
{
carry=0;
ptr[i]=ch;
}
}
}
for(i=a.num+b.num;i>0&&ptr[i-1]==0;i--);
num=i+na+nb;
if(cap>=num)
{
memcpy(val,newval,num);
delete[]newval;
}
else
{
cap=newcap;
delete[]val;
val=newval;
}
a.val=b.val=NULL;
return*this;
}
decnum&decnum::operator/=(constdecnum&x)
{
charch,carry,fac;
decnumtmp;
inti;
if(x.num==0)return*this;
if(num<x.num)
{
num=0;
return*this;
}
if(sign==x.sign)
sign=0;
else
sign=1;
char*newval=newchar[num-x.num+1];
memset(newval,0,num-x.num+1);
carry=0;
fac=x.val[x.num-1]+1;
tmp.val=val+num-x.num+1;
tmp.cap=tmp.num=x.num-1;
for(i=num-1;i>=x.num-1;i--)
{
tmp.val--;
tmp.num++;
ch=(carry*10+val[i])/fac;
tmp-=x*ch;
while(tmp>=x)
{
tmp-=x;
ch++;
}
newval[i-x.num+1]=ch;
carry=val[i];
}
tmp.val=NULL;
for(i=num-x.num+1;i>0&&newval[i-1]==0;i--);
num=i;
delete[]val;
val=newval;
return*this;
}
decnum&decnum::operator%=(constdecnum&x)
{
charch,carry,fac;
decnumtmp;
inti;
if(x.num==0)return*this;
if(num<x.num)return*this;
carry=0;
fac=x.val[x.num-1]+1;
tmp.val=val+num-x.num+1;
tmp.num=x.num-1;
for(i=num-1;i>=x.num-1;i--)
{
tmp.val--;
tmp.num++;
ch=(carry*10+val[i])/fac;
tmp-=x*ch;
while(tmp>=x)
{
tmp-=x;
ch++;
}
carry=val[i];
}
tmp.val=NULL;
num=tmp.num;
return*this;
}
decnumdecnum::operator+(constdecnum&x)const
{
decnumtmp=*this;
returntmp+=x;
}
decnumdecnum::operator-(constdecnum&x)const
{
decnumtmp=*this;
returntmp-=x;
}
decnumdecnum::operator*(constdecnum&x)const
{
decnumtmp=*this;
returntmp*=x;
}
decnumdecnum::operator/(constdecnum&x)const
{
decnumtmp=*this;
returntmp/=x;
}
decnumdecnum::operator%(constdecnum&x)const
{
decnumtmp=*this;
returntmp%=x;
}
decnumabs(constdecnum&x)
{
decnumtmp(x);
tmp.sign=0;
returntmp;
}
decnumpow(constdecnum&x,intn)
{
decnumtmp(1),fac(x);
for(;n>0;n>>=1)
{
if(n&0x01)
tmp*=fac;
fac*=fac;
}
returntmp;
}
chardecnum::root_1(intn)
{
charr=(int)(pow(1+val[num-1],1.0/n)*pow(10,(num-1.0)/n));
for(;r>0&&pow(decnum(r),n)>*this;r--);
returnr;
}
booldecnum::ispow(intn,decnum&r)const
{
if(num==0)
{
r.num=0;
returntrue;
}
if(sign==1&&(n&1==0))
{
r.num=0;
returnfalse;
}
decnumtmp,p;
r.cap=r.num=(num+n-1)/n;
r.val=newchar[r.num];
r.sign=sign;
memset(r.val,0,r.num);
tmp.val=val+(r.num-1)*n;
tmp.num=num-(r.num-1)*n;
r.val[r.num-1]=tmp.root_1(n);
tmp.val=newchar[r.num+1];
tmp.cap=r.num+1;
intv;
p=pow(r,n);
if(p==*this)returntrue;
for(inti=r.num-2;i>=0;i--)
{
memset(tmp.val,0,i+1);
tmp.val[i]=1;
tmp.num=i+1;
tmp+=r;
p=(*this-p)/(pow(tmp,n)-p);
if(p.num>1)
v=9;
elseif(p.num>0)
v=p.val[0];
else
v=0;
for(;v>=0;v--)
{
r.val[i]=v;
p=pow(r,n);
if(p==*this)
returntrue;
if(p<*this)
break;
}
}
returnfalse;
}
booldecnum::ispow()const
{
decnumr,dec2("2",1);
if(ispow(2,r))returntrue;
for(intn=3;r>dec2;n+=2)
{
if(ispow(n,r))returntrue;
}
returnfalse;
}
decnumroot(constdecnum&x,intn)
{
decnumr;
x.ispow(n,r);
returnr;
}
decnumdiv(constdecnum&x,constdecnum&y,decnum&r)
{
charch,carry,fac;
decnumd=x,tmp;
inti;
if(y.num==0)returnx;
if(d.num<y.num)
{
r=x;
d=0;
returnd;
}
char*newval=newchar[d.num-y.num+1];
memset(newval,0,d.num-y.num+1);
carry=0;
fac=y.val[y.num-1]+1;
tmp.val=d.val+d.num-y.num+1;
tmp.num=y.num-1;
for(i=d.num-1;i>=y.num-1;i--)
{
tmp.val--;
tmp.num++;
ch=(carry*10+d.val[i])/fac;
tmp-=y*ch;
while(tmp>=y)
{
tmp-=y;
ch++;
}
newval[i-y.num+1]=ch;
carry=d.val[i];
}
r=tmp;
tmp.val=NULL;
for(i=d.num-y.num+1;i>0&&newval[i-1]==0;i--);
d.num=i;
delete[]d.val;
d.val=newval;
returnd;
}
booloperator==(constdecnum&x,constdecnum&y)
{
if(x.sign!=y.sign)returnfalse;
if(x.num!=y.num)returnfalse;
for(inti=0;i<x.num;i++)
{
if(x.val[i]!=y.val[i])
returnfalse;
}
returntrue;
}
booloperator!=(constdecnum&x,constdecnum&y)
{
return!(x==y);
}
booloperator>(constdecnum&x,constdecnum&y)
{
if(x.sign>y.sign)returnfalse;
if(x.sign<y.sign)returntrue;
boolretval=(x.sign==0);
if(x.num>y.num)returnretval;
if(x.num<y.num)return!retval;
for(inti=x.num-1;i>=0;i--)
{
if(x.val[i]>y.val[i])
returnretval;
elseif(x.val[i]<y.val[i])
return!retval;
}
returnfalse;
}
booloperator<(constdecnum&x,constdecnum&y)
{
returny>x;
}
booloperator>=(constdecnum&x,constdecnum&y)
{
if(x.sign>y.sign)returnfalse;
if(x.sign<y.sign)returntrue;
boolretval=(x.sign==0);
if(x.num>y.num)returnretval;
if(x.num<y.num)return!retval;
for(inti=x.num-1;i>=0;i--)
{
if(x.val[i]>y.val[i])
returnretval;
elseif(x.val[i]<y.val[i])
return!retval;
}
returntrue;
}
booloperator<=(constdecnum&x,constdecnum&y)
{
returny>=x;
}
ostream&operator<<(ostream&os,constdecnum&x)
{
if(x.size()==0)
os<<0;
else
{
if(x.sign==1)
os<<"-";
for(inti=x.size()-1;i>=0;i--)
os<<(int)x.val[i];
}
returnos;
}
测试代码:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
#include
<
iostream
>
#include < string >
using namespace std;
#include " decnum.h "
int main()
{
decnumx,y,r;
string line;
size_tn = 0 ;
cout << " inputx: " << endl;
getline(cin,line);
x = decnum(line.c_str(),line.length());
cout << " inputy: " << endl;
getline(cin,line);
y = decnum(line.c_str(),line.length());
cout << " x= " << x << endl;
cout << " y= " << y << endl;
cout << " x*y= " << x * y << endl;
cout << " x/y= " << x / y << endl;
cout << " x%y= " << x % y << endl;
cout << " div(x,y)= " << div(x,y,r) << endl;
cout << " mod(x,y)= " << r << endl;
cout << " y^2= " << pow(y, 2 ) << endl;
cout << " x^1/2= " << root(x, 2 ) << endl;
cout << " xispow= " << x.ispow() << endl;
system( " pause " );
return 0 ;
}
#include < string >
using namespace std;
#include " decnum.h "
int main()
{
decnumx,y,r;
string line;
size_tn = 0 ;
cout << " inputx: " << endl;
getline(cin,line);
x = decnum(line.c_str(),line.length());
cout << " inputy: " << endl;
getline(cin,line);
y = decnum(line.c_str(),line.length());
cout << " x= " << x << endl;
cout << " y= " << y << endl;
cout << " x*y= " << x * y << endl;
cout << " x/y= " << x / y << endl;
cout << " x%y= " << x % y << endl;
cout << " div(x,y)= " << div(x,y,r) << endl;
cout << " mod(x,y)= " << r << endl;
cout << " y^2= " << pow(y, 2 ) << endl;
cout << " x^1/2= " << root(x, 2 ) << endl;
cout << " xispow= " << x.ispow() << endl;
system( " pause " );
return 0 ;
}