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