大數運算 整型運算浮點後續再補充

/*
 * Date: 2006-08-14
 * Ver : 0.1 
 */

#ifndef _LN_H
#define _LN_H
#include <memory.h>
#define STRING_LENGTH 100

typedef enum
{
 NONE_TYPE = 0,
 HEX_TYPE = 1,
 BCD_TYPE = 2
}DATA_STRING_TYPE;

class ln
{
public:
 ln():dt(NONE_TYPE),sign(0){memset(ds,0,STRING_LENGTH);}
 ~ln(){}
 ln(const ln&);
 ln(const int);
 ln& operator = (const ln&); 
 ln& operator = (const int);
 ln& operator = (const char*);
 ln& operator / (const ln&);
 ln& operator +=(ln);
 ln& operator *=(const ln);
 ln& operator -=(ln);
 ln& operator /=(ln);
 ln& operator <<=(unsigned int n);
 ln& operator >>=(unsigned int n);

 friend ln operator   +  ( ln, ln );
 friend bool operator <  ( ln, ln );
 friend bool operator == ( ln, ln );
 friend bool operator >  ( ln, ln );
 friend bool operator >= ( ln, ln );
 operator int();

private:
 ln& operator *=(char mul);
protected:
 void strs2hexs(char*, int );   //將字符串轉成數字格式
 void hexs2strs(char*, int );   //將數字轉成字符串格式 
 void hexscalco(char*, int&);   //數字進行加法溢出後進位運算過程
 void bcdscalco(char*, int&);   //數字進行加法溢出後進位運算過程
 char hexscalcc(char*, int&);   //數字進行減法溢出後借位運算過程,返回符號
 char bcdscalcc(char*, int&);   //數字進行減法溢出後借位運算過程,返回符號
 void killhead0(ln&, unsigned int);  //消去前置0
 void killtail0(ln&, unsigned int);  //消去後綴0
 void herohead0(ln&, int);    //增加前置0
 void herotail0(ln&, unsigned int);  //消去後綴0

 void hexs2bcds(char*, unsigned int); 
 char hex2bcd(char hex) { return ((hex/10)<<4)|(hex%10);}
private: 
 char ds[STRING_LENGTH];
 DATA_STRING_TYPE dt;
 char sign;
 char fn;        //小數點位數
};
#endif

#include "ln.h"
#include "string.h"
#include "stdlib.h"

ln::ln(const ln& that)
{
 *this = that;
}

ln::ln(const int n)
{
 *this = n;
}
ln& ln::operator = (const ln& that)
{
 dt = that.dt;
 sign = that.sign;
 memcpy(ds, that.ds, STRING_LENGTH);
 return *this;
}

ln& ln::operator = (const int n)
{
 int m = n;
 if(m<0)
 {
  sign = 1;
  m = -m;
 }
 _itoa(m, ds, 10);
 return *this;
}
ln& ln::operator = (const char* str)
{
 sign = 0;
 memcpy(ds,str,STRING_LENGTH);
 return *this;
}
ln& ln::operator / (const ln& that)
{
 return *this;
}
ln& ln::operator +=(ln that)
{
 ln tn = that;
 int large = 0, diff = 0;
 char *plg = 0, *plt = 0;
 
 if(sign^that.sign)
 {
  if(sign)
  {
   sign = that.sign;
   that -= *this;
   *this = that;
   return *this;
  }
  that.sign = sign;
  *this -= that;
  return *this;
 }

 large = strlen(plg=const_cast<char*>(ds));
 diff = strlen(plt=const_cast<char*>(tn.ds));

 strs2hexs(ds, large);
 strs2hexs(tn.ds, diff);

 if( large-diff < 0 )
 {
  large ^= diff;
  diff  ^= large;
  large ^= diff;

  plg = const_cast<char*>(tn.ds);
  plt = ds;
 }
 diff = large - diff;
 for( int i = large-1; i >= diff; i-- )
 {
  plg[i] += plt[i-diff];
 }
 hexs2bcds(plg, large);
 bcdscalco(plg, large);
 if(ds!=plg)
  *this = tn;
 hexs2strs(ds, large);
 return *this;
}

 

ln& ln::operator *=(ln that)
{
 ln tn1, tn2;
 int thislen = strlen(ds), thatlen = strlen(that.ds);
 int i = 0;
 char ts = 0;
 ts = sign^that.sign;

 sign = 0;
 that.sign = 0;
 
 tn1 = *this;
 strs2hexs(const_cast<char*>(that.ds), thatlen);
 for( i = thatlen-1; i >=0; i-- )
 {
  tn1 *= that.ds[i];
  tn2 += tn1;
  ds[thislen] = '0';
  ds[thislen+1] = 0;
  thislen++;
  tn1 = *this;
 }
 *this = tn2;
 sign = ts;
 return *this;
}

ln& ln::operator -=(ln that)
{
 char s = 0;
 int large = 0, diff = 0, i = 0;
 
 if(sign^that.sign)
 {
  that.sign ^= sign;
  *this += that;
  return *this;
 }

 if(*this<that)
  s = 1;
 sign = 0;
 that.sign = 0;
 if(*this<that)
 {
  that -= *this;
  *this = that;
  sign = s;
  return *this;
 }

 large=strlen(ds);
 diff = large - strlen(that.ds);

 herohead0(that, diff);
 strs2hexs(ds, strlen(ds));
 strs2hexs(that.ds, strlen(that.ds));

 for( i = large-1; i >= 0; i-- )
  ds[i] -= that.ds[i];

 bcdscalcc(ds, large);
 hexs2strs(ds, large);
 sign = s;
 return *this;
}
ln& ln::operator /= (ln that)
{
 char ts = 0;
 unsigned int i = 0, count = 0;
 ln tn = 0  ;

 ts = sign^that.sign;
 sign = 0;
 that.sign = 0;
 
 if(*this < that)
 {
  *this = 0;
  return *this;
 }
 count = strlen(ds)-strlen(that.ds);
 herotail0(that, count);
 
 for( i = 0; i < count+1; i++ )
 {
  while(*this>=that)
  {
   tn += 1;
   *this -= that;
   killhead0(*this, strlen(ds));
  }
  tn <<= 1;
  killtail0(that, 1);
 }
 tn >>= 1;
 *this = tn;
 sign = ts;
 return *this;
}


ln& ln::operator <<=(unsigned int n)
{
 herotail0(*this, n);
 return *this;
}
ln& ln::operator >>=(unsigned int n)
{

 int ll = strlen(ds), m = n;
 if(ll<=n)
 {
  *this = 0;
  return *this;
 }
 while(n)
  ds[ll-n--] = '0';
 killtail0(*this, m);
 return *this;
}

ln operator + (ln rgh, ln lgh)
{
 rgh += lgh;
 return rgh;
}
bool operator < (ln rgh, ln lgh )
{
 int rl=  0, ll = 0;

 if(rgh.sign^lgh.sign)
  return rgh.sign;
 rgh.killhead0(rgh, strlen(rgh.ds));
 rgh.killhead0(lgh, strlen(lgh.ds));

 if((rl=strlen(const_cast<char*>(rgh.ds)))==(ll=strlen(const_cast<char*>(lgh.ds))))
 {
  if(strcmp(rgh.ds, lgh.ds)==0)
   return false;
 }
 if(!rgh.sign && rl>ll)
  return false;
 if(rl==ll)
 {
  if(!rgh.sign && strcmp(rgh.ds, lgh.ds)>0)
   return false;
 }

 return true;
}
bool operator == ( ln rgh, ln lgh)
{
 rgh.killhead0(rgh, strlen(rgh.ds));
 rgh.killhead0(lgh, strlen(lgh.ds));
 if( !(rgh.sign^lgh.sign) && strcmp(rgh.ds, lgh.ds)==0)
  return true;
 return false;
}
bool operator > ( ln rgh, ln lgh)
{
 if( rgh<lgh || rgh==lgh )
  return false;
 return true;
}

bool operator >= ( ln rgh, ln lgh)
{
 return !(rgh<lgh);
}


ln::operator int()
{
 int ll = 0, tr = 0;

 ll = strlen(ds);
 strs2hexs(ds,ll);
 for( int i = 0; i < ll; i++ )
 {
  tr *= 10;
  tr += ds[i];
 }
 if(sign)
  tr = -tr;
 return tr;
}

 

 

ln& ln::operator *=(char mul)
{
 int thislen = strlen(ds);

 strs2hexs(ds,thislen);
 for( int i = thislen-1; i >=0; i-- )
  ds[i] *= mul;
 hexs2bcds(ds, thislen);
 bcdscalco(ds, thislen);
 hexs2strs(ds,thislen);
 return *this;

}
void ln::strs2hexs(char* pstr, int len)
{
 int i = 0;
 for( i = 0; i < len; i++ )
 {
  if(pstr[i]<='9'&&pstr[i]>='0') 
   pstr[i] -= '0';
  else if(pstr[i]>='a' && pstr[i] <= 'z')
   pstr[i] -= 'a'-10;
  else if( pstr[i]>='A' && pstr[i] <= 'Z')
   pstr[i] -= 'A'-10;
  else
  {
   pstr[i] = 0;
   break;
  }
 }
}

void ln::hexs2strs(char* phex, int len)
{
 int i = 0;
 for( i = 0; i < len; i++ )
 {
  if(phex[i]<=9&&phex[i]>=0) 
   phex[i] += '0';
  else
   phex[i] += 'a' - 10;
 }
}

void ln::hexscalco(char* phex, int& len)
{
 int i = 0;
 for( i = len-1; i > 0; i-- )
 {
  phex[i-1] += (phex[i]>>4)&0x0F;
  phex[i] &= 0x0F;
 }
 if(phex[i]&0xF0)
 {
  phex[len+1] = 0;
  for( i = len-1; i > 0; i-- )
   phex[i+1] = phex[i];
  phex[i+1] = phex[i]&0x0F;
  phex[i] >>= 4;
  len++;
 }
}
void ln::bcdscalco(char* phex, int& len)
{
 int i = 0;
 char temp = 0;
 for( i = len-1; i > 0; i-- )
 {
  phex[i-1] = (phex[i-1]&0xF0) + hex2bcd(((phex[i]>>4)&0x0F)+(phex[i-1]&0x0F));
  phex[i] &= 0x0F;
 }
 if(phex[i]&0xF0)
 {
  phex[len+1] = 0;
  for( i = len-1; i > 0; i-- )
   phex[i+1] = phex[i];
  phex[i+1] = phex[i]&0x0F;
  phex[i] >>= 4;
  len++;
 }
}
char ln::hexscalcc(char* phex, int& len)
{
 int i = 0;
 for( i = len-1; i > 0; i-- )
 {
  if(phex[i]&0xF0)
  {
   phex[i-1]--;
  }
  phex[i] &= 0x0F;
 }
 if(phex[i]&0xF0)
 {
  phex[i] &= 0x0F;
  return 1;
 }
 return 0;
}

char ln::bcdscalcc(char* phex, int& len)
{
 int i = 0;
 for( i = len-1; i > 0; i-- )
 {
  if(phex[i]&0xF0)
  {
   phex[i-1]--;
  }
  phex[i] += 10;
  phex[i] %= 10;
 }
 if(phex[i]&0xF0)
 {
  phex[i] += 10;
  phex[i] %= 10;
  return 1;
 }
 return 0;
}
void ln::killhead0(ln& that, unsigned int n)
{
 char* pds = that.ds;
 unsigned int i = 0;
 for( i = 0; i < strlen(that.ds)&&n; i++, n-- )
 {
  if(that.ds[i]=='0')
   pds++;
  else
   break;
 }
 if(pds==that.ds)
  return;
 for( i = 0; i < strlen(that.ds)+pds-that.ds; i++ )
  that.ds[i] = pds[i];
 that.ds[i] = 0;
}
void ln::killtail0(ln& that, unsigned int n)
{
 int i = strlen(that.ds);
 while(n--)
 {
  if(that.ds[i-1]=='0')
   that.ds[i-1] = 0;
  else
   break;
 }
}
void ln::herohead0(ln& that, int n)
{
 char* pds = that.ds;
 int i = 0;
 for( i = strlen(that.ds); i >= 0 ; i-- )
  pds[i+n] = that.ds[i];
 for( i = 0; i < n; i++ )
  pds[i] = '0';
}

void ln::herotail0(ln& that, unsigned int n)
{
 unsigned int ll = strlen(that.ds), i = 0;
 for( i = 0; i < n; i++)
  that.ds[ll+i] = '0';
 that.ds[ll+i] = 0;
}

void ln::hexs2bcds(char* src, unsigned int n)
{
 while (n--)
 {
  src[n] = hex2bcd(src[n]);
 }

發佈了53 篇原創文章 · 獲贊 1 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章