Манипулирование с целыми числами произвольной длины - (реферат)
p>for ( COUNT si=Length+LeftLimit-1, ki=0 ; kichar a=DecVal(string[si]);
if (a==ILLEGAL)
{
NotDigit();
return;
}
(pv->body)[ki]=a;
if (si! =LeftLimit)
{
char a=DecVal(string[si-1]);
if (a==ILLEGAL)
{
NotDigit();
return;
}
(pv->body)[ki]+=10*a;
}
}
(pv->len)=Length;
}
}
}
void unlim: :NotDigit()
{
error("Not digit symbol in string. String ignored. Value=0"); delete pv->body;
init0();
}
unlim: :unlim(unlim &arg)
{
(arg. pv)->HowMany++;
pv=arg. pv;
sign=arg. sign;
}
unlim &unlim: :operator=(unlim &arg)
{
(arg. pv)->HowMany++;
if ( --(pv->HowMany)==0 )
{
delete pv->body;
delete pv;
}
pv=arg. pv;
sign=arg. sign;
return *this;
}
unlim &unlim: :operator=(char *string)
{
return *this=unlim(string);
}
ostream &operator {
if (x. sign==MINUS)
s for ( COUNT i=((x. pv)->len) ; i>0 ; i-- )
s return s;
}
int operator! =(unlim &a, unlim &b)
{
if ( (a. pv)->len ! = (b. pv)->len)
return TRUE;
if (a. sign! =b. sign)
return TRUE;
COUNT length=((a. pv)->len)/2+((a. pv)->len)%2;
for ( COUNT i=0 ; i if (a[i]! =b[i])
return TRUE;
return FALSE;
}
int operator {
if (a. sign! =b. sign)
return a. sign==MINUS;
if ( (a. pv)->len == (b. pv)->len )
{
COUNT i=((a. pv)->len)-1;
while ( a. digit(i) == b. digit(i) )
{
if (i==0)
return FALSE;
i--;
}
char
aLess= a. digit(i) < b. digit(i),
SignPlus= a. sign==PLUS;
return ( aLess && SignPlus) || ( ! aLess && ! SignPlus );
}
else
char
aShort= (a. pv)->len < (b. pv)->len,
SignPlus= a. sign==PLUS;
return ( aShort && SignPlus )
}
inline int operator ==(unlim &a, unlim &b)
{
return ! (a! =b);
}
inline int operator
inline int operator >=(unlim &a, unlim &b)
{
return ! (a }
inline int operator >(unlim &a, unlim &b)
{
return ! (a }
inline unlim operator +(unlim &x)
{
return x;
}
unlim abs(unlim &x)
{
unlim r=x;
r. sign=PLUS;
return r;
}
unlim operator -(unlim &x)
{
if ( (x. pv)->len==1 && x[0]==0 )
{
unlim y;
return y;
}
unlim y=x;
if (x. sign==PLUS)
y. sign=MINUS;
else
y. sign=PLUS;
return y;
}
void unlim: :optimize()
{
COUNT i=pv->len/2+pv->len%2-1;
char optimized=FALSE;
while (pv->body[i]==0)
{
optimized=TRUE;
if (i--==0)
{
init0();
return;
}
}
if (optimized)
{
char *NewBody=new char[++i];
for (COUNT ni=0; ni NewBody[ni]=pv->body[ni];
delete pv->body;
pv->body=NewBody;
pv->len=(i--)*2;
}
if ( (pv->body[i]/10)==0 && (pv->len%2)==0 )
pv->len--;
}
inline COUNT max (COUNT a, COUNT b)
{
return (a>b)? a: b;
}
unlim operator +(unlim &a, unlim &b)
{
unlim r;
delete (r. pv)->body;
if (a. sign==b. sign)
{
r. sign=a. sign;
COUNT
rlen=max( (a. pv)->len, (b. pv)->len )+1,
alen=(a. pv)->len/2+(a. pv)->len%2,
blen=(b. pv)->len/2+(b. pv)->len%2;
(r. pv)->len=rlen;
rlen=rlen/2+rlen%2;
(r. pv)->body=new char[rlen];
*(r. pv)->body=0;
for (COUNT i=0; i {
unsigned char sum=( i
r[i+1]=sum/100;
}
if ( r. digit( (r. pv)->len-1 )==0 )
(r. pv)->len--;
}
else
{
unlim
aa=a,
bb=b;
if (abs(a) {
aa=b;
bb=a;
}
r. sign=aa. sign;
COUNT
rlen=(aa. pv)->len,
blen=(bb. pv)->len/2+(bb. pv)->len%2;
(r. pv)->len=rlen;
rlen=rlen/2+rlen%2;
(r. pv)->body=new char[rlen];
*(r. pv)->body=0;
for (COUNT i=0; i {
char sub=aa[i]-( i if (sub {
r[i+1]=-1;
sub+=100;
}
else
r[i+1]=0;
r[i]=sub;
}
r. optimize();
}
return r;
}
unlim operator -(unlim &a, unlim &b)
{
return a+(-b);
}
unlim operator *(unlim &a, unlim &b)
{
unlim r;
delete (r. pv)->body;
if (a. sign==b. sign)
r. sign=PLUS;
else
r. sign=MINUS;
COUNT
rlen=(a. pv)->len+(b. pv)->len,
alen=(a. pv)->len/2+(a. pv)->len%2,
blen=(b. pv)->len/2+(b. pv)->len%2;
(r. pv)->len=rlen;
rlen=rlen/2+rlen%2;
(r. pv)->body=new char[rlen];
COUNT i;
for (i=0; i r[i]=0;
for (i=0; i {
unsigned int
next=0,
mul;
for(COUNT j=0; j {
next+=r[i+j];
mul=a[i]*b[j]+next;
r[i+j]=mul%100;
next=mul/100;
}
r[i+blen]=next;
}
if ( r. digit((r. pv)->len-1)==0 )
(r. pv)->len--;
if ( r. digit((r. pv)->len-1)==0 )
r. init0();
return r;
}