/*************************************************************\
Written By: Jabbar Ganji ganji_j@yahoo.com http://g99.blogfa.com
\*************************************************************/
class BigInt
{
private:
int n;
char* d;
int sign;
public:
~BigInt ();
BigInt (long int x=0, int nn=-1);
BigInt (int nn, char*);
BigInt (char*);
void Kill ();
BigInt operator* (int x);
void operator*= (int x);
operator char*();
void operator= (BigInt&);
BigInt operator+ (BigInt&);
void operator+= (BigInt&);
void operator*= (BigInt&);
int operator== (BigInt& b);
int operator!= (BigInt& b);
int operator< (BigInt& b);
int operator> (BigInt& b);
int operator<= (BigInt& b);
int operator>= (BigInt& b);
BigInt operator- ();
BigInt operator- (BigInt& b);
BigInt operator* (BigInt&);
friend BigInt operator* (int x, BigInt& b);
char GetDigit (int);
void CopyTo (char* s);
void KillLeftZeros();
BigInt& ToggleSign () { sign=1-sign; return *this; }
BigInt& SetPositiveSign() { sign=1; return *this; }
BigInt& SetNegativeSign() { sign=0; return *this; }
int GetSign () { return sign; }
int IsPositive () { return sign; }
int IsZero ();
BigInt& SetSign(int sgn) { sign=sgn; return *this; }
BigInt Abs() { BigInt b; b=*this; return b.SetPositiveSign(); }
private:
void operator<<= (int k);
BigInt operator<< (int);
};
int BigInt::operator==(BigInt& b)
{
if(sign!=b.sign && !IsZero())
return 0;
int i;
for(i=0; i<n || i<b.n; i++)
if(GetDigit(i)!=b.GetDigit(i))
return 0;
return 1;
}
int BigInt::operator!=(BigInt& b)
{
return !(*this==b);
}
int BigInt::operator<(BigInt& b)
{
if(sign!=b.sign)
return !sign;
int i, d1, d2, maxn = n>b.n ? n : b.n;
for(i=maxn-1; i>=0; i--)
{
d1=GetDigit(i);
d2=b.GetDigit(i);
if(d1==d2)
continue;
return (d1<d2) == (sign!=0);
}
return 0;
}
int BigInt::operator<=(BigInt& b)
{
return *this<b || *this==b;
}
int BigInt::operator>(BigInt& b)
{
return !(*this<=b);
}
int BigInt::operator>=(BigInt& b)
{
return !(*this<b);
}
BigInt BigInt::operator-()
{
BigInt b;
b=*this;
return b.ToggleSign();
}
BigInt BigInt::operator-(BigInt& b)
{
return *this+(-b);
}
void BigInt::KillLeftZeros()
{
int i, k;
for(i=n-1; i>0 && !d[i]; i--)
;
if(i==0)
return;
i++;
BigInt r(0, i);
for(k=0; k<i; k++)
r.d[k]=d[k];
Kill();
r.sign=sign;
*this=r;
}
BigInt::operator char*()
{
KillLeftZeros();
static char* ss=new char[n+2];
CopyTo(ss);
return ss;
}
void BigInt::CopyTo(char* s)
{
int i;
s[0]=sign ? '+' : '-';
for(i=0; i<n; i++)
s[i+1]=d[n-i-1]+'0';
s[i+1]=0;
}
BigInt::~BigInt()
{
Kill();
}
char BigInt::GetDigit(int i)
{
return i<n ? d[i] : 0;
}
BigInt::BigInt(int nn, char* s)
{
int i, len=-1;
sign=1;
if(s[0]=='-' || s[0]=='+')
{
sign= s[0]=='+';
s++;
}
while(s[++len])
;
n=nn;
d=new char[n];
for(i=0; s[i]; i++)
d[i]=s[len-i-1]-'0';
for(; i<n; i++)
d[i]=0;
}
BigInt::BigInt(char* s)
{
int i, len=-1;
sign=1;
if(s[0]=='-' || s[0]=='+')
{
sign= s[0]=='+';
s++;
}
while(s[++len])
;
n=len;
d=new char[n];
for(i=0; i<len; i++)
d[i]=s[len-i-1]-'0';
for(; i<n; i++)
d[i]=0;
}
void BigInt::Kill()
{
n=0;
if(!d)
return;
if(n<2)
if(n==1)
{
delete d;
d=0;
}
else
return;
delete[] d;
d=0;
}
void BigInt::operator=(BigInt& b)
{
if(n<b.n)
{
Kill();
n=b.n;
d=new char[n];
}
int i;
for(i=0; i<b.n; i++)
d[i]=b.d[i];
for(; i<n; i++)
d[i]=0;
sign=b.sign;
}
BigInt::BigInt(long int x, int nn)
{
int i;
sign=1;
if(x<0)
{
x=-x;
sign=0;
}
if(nn<=0)
{
long int xt=x/10;
for(nn=1; xt>0; nn++, xt/=10)
;
}
n=nn;
d=new char[n];
for(i=0; x; x/=10, i++)
d[i]=x%10;
for(; i<n; i++)
d[i]=0;
}
BigInt BigInt::operator+(BigInt& b)
{
int i, subtract=0, rsign, reverse=0;
if(sign==b.sign)
rsign=sign;
else
{
subtract=1;
int pos1=sign;
sign=b.sign=1;
if(*this>b)
rsign=pos1;
else
{
rsign=1-pos1;
reverse=1;
}
sign=pos1;
b.sign=1-pos1;
}
int maxn=n>b.n ? n:b.n;
BigInt r(0, maxn+1);
if(!subtract)
for(i=0; i<maxn; i++)
{
r.d[i]+=GetDigit(i)+b.GetDigit(i);
if(r.d[i]>9)
{
r.d[i]-=10;
r.d[i+1]++;
}
}
else
if(reverse)
for(i=0; i<maxn; i++)
{
r.d[i]+=b.GetDigit(i)-GetDigit(i);
if(r.d[i]<0)
{
r.d[i]+=10;
r.d[i+1]--;
}
}
else
for(i=0; i<maxn; i++)
{
r.d[i]+=GetDigit(i)-b.GetDigit(i);
if(r.d[i]<0)
{
r.d[i]+=10;
r.d[i+1]--;
}
}
r.sign=rsign;
return r;//.SetSign(rsign);
}
BigInt BigInt::operator*(int x)
{
int i, y, nn;
int rsign=(sign!=0) == (x>0);
if(x<0)
x=-x;
for(nn=n+1, y=x; y; y/=10, nn++)
;
long int* dd=new long int[nn];
for(i=0; i<n; i++)
dd[i]=(long int) x * d[i];
for( ; i<nn; i++)
dd[i]=0;
for(i=0; i<nn-1; i++)
{
dd[i+1]+=dd[i]/10;
dd[i]%=10;
}
for(i=nn-1; i>=0 && !dd[i]; i--)
;
nn=i+1;
if(nn<=0)
{
delete[] dd;
return BigInt(0, 1);
}
BigInt r(0, nn);
for(i=0; i<nn; i++)
r.d[i]=(char) dd[i];
delete[] dd;
r.sign=rsign;
return r;
}
void BigInt::operator+=(BigInt& b)
{
*this=*this+b;
}
void BigInt::operator*=(BigInt& b)
{
*this=*this*b;
}
BigInt operator*(int x, BigInt& b)
{
return b*x ;
}
void BigInt::operator*=(int x)
{
*this=*this*x;
}
int BigInt::IsZero()
{
int i;
for(i=0; i<n; i++)
if(d[i]>0)
return 0;
return 1;
}
BigInt BigInt::operator*(BigInt& b)
{
int rsign= sign==b.sign;
BigInt r(0, n+b.n), t;
int i;
for(i=0; i<b.n; i++)
{
t= *this*b.d[i];
t<<=i;
r+=t;
}
r.KillLeftZeros();
r.sign=rsign;
return r;
}
void BigInt::operator<<=(int k)
{
*this=*this << k;
}
BigInt BigInt::operator<<(int k)
{
int i;
BigInt r(0, n+k);
for(i=0; i<n; i++)
r.d[i+k]=d[i];
r.sign=sign;
return r;
}
//////////////////////////// T E S T /////////////////////////
#include <stdio.h>
#include <conio.h>
void main()
{
clrscr();
int i;
BigInt f1(-25), f2(-35);
printf((char*) (f1-f2));
getch();
}
