برق - کامپیوتر - برنامه نویسی

تبادل اطلاعات علمی در زمینه ی برق - جبار گنجی

/*************************************************************\
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();
}