?? slnum.cpp
字號:
// slnum.cpp: implementation of the slnum class.
//定義一個超高精度的類slnum的實現(xiàn)算法代碼,用以實現(xiàn)超過20位有效數(shù)字整型數(shù)值
//的運算,并具有兼容已有整型數(shù)據(jù)int的能力,能與int數(shù)據(jù)混合運算。
//版權(quán)所有,貴州師范大學(xué)數(shù)學(xué)與計算機科學(xué)系2001成計本班羅國文(貴州天柱二中)
//凡引用本文件不得刪除上述信息
//////////////////////////////////////////////////////////////////////
#include<string.h>
#include "slnum.h"
#include <stdlib.h>
#include <math.h>
#define z1 "0"
#define z2 "00"
#define z3 "000"
#define z4 "0000"
#define R 10000
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//空初始化
slnum::slnum()
{
sign=1;
arr_n=1;
sl=new long[arr_n];
sl[0] =0;
soure=new char[8];
soure="0";
}
//把數(shù)值字符串設(shè)置值給slnum類對象
void slnum::setval(const char * s)
{
char mySIGN;
char temp[5];
int len,i,j=4,k=0;
mySIGN=s[0];
switch(mySIGN)
{
case '-':
case '+':
{
if(mySIGN=='-')sign=-1;
if(mySIGN=='+')sign=+1;
len=strlen(s);
soure=new char[len+1];
strcpy(soure,s);
for(int n=0;n<=len;n++)soure[n]=soure[n+1];
len=strlen(soure);
if (len%4==0) arr_n=(int)len/4;
else arr_n=(int)(len/4+1);
sl=new long[arr_n];
for(i=len;i>=0;i--) //把數(shù)值串賦值給數(shù)組
{
temp[j]=soure[i];
if(i==0&&j)
for(int q=0;q<j;q++)temp[q]='0';
if(j==0||i==0)
{
temp[4]='\0';
sl[k]=atol(temp);
j=4;k++;
}
j--;
}
break;
}
default:
{
sign=+1;
len=strlen(s);
soure=new char[len+1];
strcpy(soure,s);
if (len%4==0) arr_n=(int)len/4;
else arr_n=(int)(len/4+1);
sl=new long[arr_n];
for(i=len;i>=0;i--) //把數(shù)值串賦值給數(shù)組
{
temp[j]=soure[i];
if(i==0&&j)
for(int q=0;q<j;q++)temp[q]='0';
if(j==0||i==0)
{
temp[4]='\0';
sl[k]=atol(temp);
j=4;k++;
}
j--;
}
break;
}
}
}
//獲取值,以字符串方式取出
char * slnum::getval ()
{
char * temp,*e="-";
if(sign==-1)
{
temp=new char[strlen(soure)+2];
strcpy(temp,e);
strcat(temp,soure);
}
else
{
temp=new char[strlen(soure)+1];
strcpy(temp,soure);
}
return temp;
}
//以數(shù)值字符串進行初始化
slnum::slnum(const char * s)
{
setval(s);
}
//大于比較:真值為ture;假值為flase
bool slnum::operator >(const slnum &num)
{
if(sign >num.sign ) return true;
if (sign==1&&num.sign==1)
{
if (strlen(soure) >strlen(num.soure) ) return true;
if ((strlen(soure) ==strlen(num.soure))&&(strcmp(soure ,num.soure )>0)) return true;
}
if (sign==-1&&num.sign==-1)
{
if (strlen(soure) <strlen(num.soure) ) return true;
if ((strlen(soure) ==strlen(num.soure))&&(strcmp(soure ,num.soure )<0)) return true;
}
return false;
}
//等于比較:真值為ture;假值為flase
bool slnum::operator ==(const slnum &num)
{
if ((sign==num.sign)&&(strcmp(soure ,num.soure )==0)) return true;
else return false;
}
//不等于比較:真值為ture;假值為flase
bool slnum::operator !=(const slnum &num)
{
if ((sign!=num.sign)||(strcmp(soure ,num.soure )!=0)) return true;
else return false;
}
//大于等于比較:真值為ture;假值為flase
bool slnum::operator >=(const slnum &num)
{
if(*this>num||*this==num)return true;
else return false;
}
//小于比較:真值為ture;假值為flase
bool slnum::operator <(const slnum &num)
{
if(!(*this>=num))return true;
else return false;
}
//小于等于比較:真值為ture;假值為flase
bool slnum::operator <=(const slnum &num)
{
if(!(*this>num)) return true;
else return false;
}
//進位、借位調(diào)整器
void regulator(slnum *num)
{
int i;
for(i=0;i<num->arr_n ;i++)
{
if(num->sl[i]>=R) //進位調(diào)整
{
num->sl[i+1]+=num->sl[i]/R;
num->sl[i]%=R;
}
if(num->sl[i]<0) //借位調(diào)整
{
num->sl[i+1]=num->sl[i+1]-1;
num->sl[i]+=R;
}
}
}
void regulator_sign(slnum *num) //符號調(diào)整
{
int flag=1,i;
if(num->sl[num->arr_n-1]<0)flag=-1;
num->sign=flag*num->sign;
for(i=0;i<num->arr_n ;i++)num->sl[i]=flag*num->sl[i];
}
//整理數(shù)組值到串soure
void sltostr(slnum *num)
{
int i;
char * n_temp,*c_temp;
n_temp=new char[5];
c_temp=new char[5];
num->soure =new char[num->arr_n *4+4];
num->soure[0]='\0';
i=num->arr_n-1;
if(num->sl[i]) //處理高高位
{
ltoa(num->sl[i],n_temp,10) ;
strcpy(num->soure ,n_temp);
}
int l=0;
while(i) //處理高位后的各位數(shù)
{
i--;
ltoa(num->sl[i],n_temp,10);
l=4-strlen(n_temp);
if(l>0)
{
if(l==1)strcpy(c_temp,z1);
if(l==2)strcpy(c_temp,z2);
if(l==3)strcpy(c_temp,z3);
if(l==4)strcpy(c_temp,z4);
strcat(num->soure,c_temp);
}
strcat(num->soure,n_temp);
}
int len;
while(num->soure[0]=='0')//去除無效0的處理
{
len=strlen(num->soure );
for(i=0;i<len; i++)
num->soure [i]=num->soure [i+1];
}
if(num->soure[0]=='\0')strcpy(num->soure,"0");
}
//與常規(guī)整數(shù)的加運算
slnum slnum::operator +(int num)
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
slnum temp(s);
char * ss;
ss=new char[31];
itoa(num,ss,10);
slnum AA(ss);
slnum temp0;
temp0=temp+AA;
return temp0;
}
//與常規(guī)整數(shù)的減運算
slnum slnum::operator -(int num)
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
slnum temp(s); //取左操作數(shù)
char * ss;
ss=new char[31];
itoa(num,ss,10);
slnum A(ss); //取右操作數(shù)
slnum temp0;
temp0=temp-A;
return temp0;
}
//加運算
slnum slnum::operator +(const slnum &num)
{
int i;
slnum temp;
temp.arr_n =arr_n>num.arr_n ?arr_n:num.arr_n ;
if((arr_n==num.arr_n )&&abs((sl[arr_n-1]*sign+num.sl[num.arr_n-1 ]*num.sign ))>=R) ++temp.arr_n ;
temp.sl=new long[temp.arr_n ];
for(i=0;i<temp.arr_n ;i++)temp.sl[i]=0;
for(i=0;i<temp.arr_n ;i++)
{
if((i>=arr_n)&&(num.arr_n>arr_n ))temp.sl[i]=num.sl[i]*num.sign ;
if((i>=num.arr_n )&&(arr_n >num.arr_n))temp.sl[i]=sl[i]*sign;
if((i<arr_n)&&(i< num.arr_n ))temp.sl[i]=sl[i]*sign+num.sl[i]*num.sign ;
}
regulator_sign(&temp);
regulator(&temp);
sltostr(&temp);
return temp;
}
//求相反數(shù)
slnum slnum:: operator -()
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
slnum temp(s);
temp.sign *=-1;
return temp;
}
//減運算
slnum slnum::operator -(const slnum &num)
{
slnum temp,A;
A=num ;
A.sign *=-1 ;
temp=*this+A;
return temp;
}
//與常規(guī)整數(shù)的乘運算
slnum slnum::operator *(int num)
{
int i,j;
char * ss;
ss=new char [31];
itoa(num ,ss,10);
slnum temp,a(ss);
temp.arr_n =arr_n+a.arr_n ;
temp.sign =sign*a.sign ;
temp.sl=new long[temp.arr_n ];
for(i=0;i<temp.arr_n ;i++)temp.sl[i]=0;
for(i=0;i<arr_n;i++)
{
for(j=0;j<a.arr_n ;j++)
{
temp.sl[i+j]+=sl[i]*a.sl[j];
}
regulator(&temp);
}
sltostr(&temp);
return temp;
}
//乘運算
slnum slnum::operator *(const slnum &num)
{
int i,j;
slnum temp;
temp.sign =sign*num.sign ;
temp.arr_n =arr_n+num.arr_n ;
temp.sl=new long[temp.arr_n ];
for(i=0;i<temp.arr_n ;i++)temp.sl[i]=0;
for(i=0;i<arr_n;i++)
{
for(j=0;j<num.arr_n ;j++)
{
temp.sl[i+j]+=sl[i]*num.sl[j];
}
regulator(&temp);
}
sltostr(&temp);
return temp;
}
//用常規(guī)整數(shù)進行賦值
void slnum::operator =(const int num)
{
char * ss;
ss=new char[31];
itoa(num,ss,10);
setval(ss);
}
//用常規(guī)整數(shù)串進行賦值
void slnum::operator =(char * num)
{
setval(num);
}
slnum abs(const slnum &num) //求絕對值
{
slnum temp;
temp=num;
temp.sign*=num.sign;
return temp;
}
//除運算:使用折半試商算法
slnum slnum::operator /(const slnum &num)
{
int i,en,quot,A,T;
slnum qt("0"),temp,num0;
num0=abs(num);
slnum sureplus("0");
en=arr_n -num.arr_n ;
if(arr_n<num.arr_n )
return qt;
else {
for( i=arr_n -1;i>en;i--)
{
sureplus=sureplus*R+sl[i];
}
;
do
{
//取下一位
sureplus=sureplus*R+sl[i];
quot=0;A=0;
while(sureplus.sign<0||sureplus>=num0 )
{
switch (sureplus.sign )
{
case 1 :
{
if (sureplus.arr_n >num0.arr_n )
quot=(sureplus.sl[sureplus.arr_n -1]*R+sureplus.sl[sureplus.arr_n -2])/num.sl[num.arr_n -1];
else quot=sureplus.sl[sureplus.arr_n -1]/num.sl[num.arr_n -1];
} break;
case -1:
{
if (sureplus.arr_n <num0.arr_n )quot=2;
else if (sureplus.arr_n >num0.arr_n )
quot=(sureplus.sl[sureplus.arr_n -1]*R+sureplus.sl[sureplus.arr_n -2])/num.sl[num.arr_n -1];
else quot=sureplus.sl[sureplus.arr_n -1]/num.sl[num.arr_n -1];
} break;
}
T=(quot+1)/2;
T=T*sureplus.sign ;
temp=T;
temp=temp*num0;
A=A+T ;
sureplus=sureplus-temp;
}
qt=qt*R;
qt=qt+A;
--i;
}
while(i>=0);
qt.sign=sign*num.sign ;
return qt;
}
}
//與整數(shù)的除運算
slnum slnum::operator /( int num)
{
char * s;
s=new char[strlen(getval())+1];
strcpy(s,getval());
slnum temp(s);
slnum qt,a;
a=num;
qt=temp/a;
return qt;
}
//求余運算
slnum slnum::operator %(const slnum &num)
{
slnum temp,sp;
sp=*this/num;
temp=sp*num;
temp=*this-temp;
return temp;
}
//與常規(guī)整數(shù)的求余運算
slnum slnum::operator %(int num)
{
char * s,*sp;
s=new char[strlen(getval())+1];
strcpy(s,getval());
slnum temp(s);
slnum surepl,a;
a=num;
surepl=temp%a;
return surepl;
}
slnum::~slnum()
{
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -