#include
#include
#include
#include
#define COUNT unsigned int
#define TRUE 1
#define FALSE 0
#define ILLEGAL 10
enum
{
PLUS,
MINUS
};
class unlim
{
public:
unlim(char*);
unlim();
unlim(unlim&);
~unlim();
unlim
&operator = (char*),
&operator = (unlim&);
friend int
operator == (unlim&,unlim&),
operator != (unlim&,unlim&),
operator > (unlim&,unlim&),
operator >= (unlim&,unlim&),
operator < (unlim&,unlim&),
operator HowMany)=1;
}
unlim::~unlim()
{
if ( --(pv->HowMany)==0 )
{
delete pv->body;
delete pv;
}
}
char DecVal(char symbol)
{
if ( isdigit(symbol) )
return symbol-'0';
return ILLEGAL;
}
unlim::unlim(char *string)
{
pv=new descriptor;
(pv->HowMany)=1;
COUNT Length=strlen(string);
if (Length==0)
{
error("Empty string assigned. Value=0");
init0();
return;
}
else
{
COUNT LeftLimit=0;
switch (string[0])
{
case '-':
sign=MINUS;
LeftLimit=1;
break;
case '+':
LeftLimit=1;
default:
sign=PLUS;
}
if (Length-LeftLimit==0)
{
error("Sign without value. Value=0");
init0();
return;
}
else
{
while (string[LeftLimit]=='0')
LeftLimit++;
if ( (Length-=LeftLimit)==0 )
{
init0();
return;
}
COUNT DestLength=Length/2+Length%2;
(pv->body)=new char[DestLength];
for ( COUNT si=Length+LeftLimit-1, ki=0 ; kibody)[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 &operatorlen)
return TRUE;
if (a.sign!=b.sign)
return TRUE;
COUNT length=((a.pv)->len)/2+((a.pv)->len)%2;
for ( COUNT i=0 ; ilen )
{
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 ) || ( !aShort && !SignPlus );
}
}
inline int operator ==(unlim &a,unlim &b)
{
return !(a!=b);
}
inline int operator 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;nibody[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;ilen/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;ilen,
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;ilen-1)==0 )
r.init0();
return r;
}
|
|