高精度整型模板
一直想写一个这样的模板,但奈何本人比较 懒 菜。。。
说明都在注释里。
行数有点多,说明主要集中在开头了。
和传统的高精有点区别,这个大概可以当做10000进制的计数运算。
每个node变量记录 -9999~9999,的4位
所以保存和运算的范围是 -1*10^40000 ~ 1*10^40000 ,4万位的整数运算
其中node在保存与运算时也是带符号的。所以sign*node就是绝对值。
#ifndef myInt_Decl
#define myInt_Decl
/*****************************************************
高精度整数模板
重载运算符:
+ , - , * , / , % , += , -= , /= , %= ,++ ,-- ;
强制类型转换 :
int -> myInt
myInt -> int
myInt ->char*
char*->myInt
私有函数:
int myInt_Judge(const myInt & a,const myInt & b);
比较大小的函数
a<b 返回 -1
a==b 返回 0
a>b 返回 1
bool carry(void);
内部调整,进位,借位,统一符号的函数
成功返回true 失败返回false
static bool myInt_Divid(const myInt & a,const myInt & b,myInt & c,myInt & d);
两数相除,求商,求余的函数
a/b==c......d
(除法和求余时间复杂度很高,在追求效率的时候请谨慎使用)
公有函数:
myInt.print();
向当前输出流 输出当前数字(10进制,无换行空格)
ps:关于类型转换的说明
myInt::myInt(const char str[],int carry_Num=10,int head=0,int tail=-1);
将str[]转换为myInt
carry_Num : 字符串中的进制(2进制 ~~ 16进制)(默认为10进制)
head : 数字在字符串中的开始下标 (默认为0)
tail : 数字在字符串中的截止下标 (默认为-1,代表字符串结尾)
在使用myInt与int类型运算时,可以使用myInt(int)进行类型转换
myInt a=myInt(int(b)) + myInt(int(c));
使用char*(myInt)后,要使用free(char *)释放内存;
char * p = char * (myInt(a));
...
free(p);
*****************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//数组长度,节点大小,幂指数,节点类型,下标类型。
#define myInt_len 10000
#define myInt_size 10000//必须为10的整数次幂
#define size_Digit 4//对应 myInt_size 有几个零 ,10^size_Digit==myInt_size
#define node_Type int
#define sub_Type int
#define positive 1
#define negative (-1)
/*
要满足的条件:
1、sub_Type的范围>下标;
2、(myInt_size^2)< node_Type 的范围;
3、 10^size_Digit==myInt_size ;
可以保存和运算的范围:
+-10^(myInt_size*size_Digit);
*/
using namespace std;
const char tranStr_a[]="0123456789ABCDEF";
const char tranStr_b[]="0123456789abcdef";
class myInt{
private:
node_Type node[myInt_len];//记录数字的数组
sub_Type len;//
int sign;//符号
bool carry(void);//进位函数
static int myInt_Judge(const myInt &,const myInt &);//比较函数 -1小于 0相等 1大于
static bool myInt_Divid(const myInt &,const myInt &,myInt &,myInt &);
public:
myInt(void);
myInt(node_Type);
myInt(const myInt&);
myInt(const char*,int,int,int);
operator int(void);
operator char*(void);//转换完成后返回字符指针,使用结束后要 free(char * str);释放内存;
friend myInt operator + (const myInt &,const myInt &);
friend myInt operator - (const myInt &,const myInt &);
friend myInt operator * (const myInt &,const myInt &);
friend myInt operator / (const myInt &,const myInt &);
friend myInt operator % (const myInt &,const myInt &);
friend myInt & operator += (myInt &,const myInt &);
friend myInt & operator -= (myInt &,const myInt &);
friend myInt & operator *= (myInt &,const myInt &);
friend myInt & operator /= (myInt &,const myInt &);
friend myInt & operator %= (myInt &,const myInt &);
friend bool operator > (const myInt &,const myInt &);
friend bool operator < (const myInt &,const myInt &);
friend bool operator >= (const myInt &,const myInt &);
friend bool operator <= (const myInt &,const myInt &);
friend bool operator == (const myInt &,const myInt &);
friend bool operator != (const myInt &,const myInt &);
friend myInt & operator ++ (myInt &);//前置
friend myInt & operator -- (myInt &);
friend myInt operator ++ (myInt &,int);//后置
friend myInt operator -- (myInt &,int);
void print(void);
};
//输出函数
void myInt::print(void)
{
char* ans=(char*)malloc(myInt_len*size_Digit*sizeof(char));
if(sign==negative)
{
sprintf(ans,"-%d",sign*node[len]);
}
else
{
sprintf(ans,"%d",sign*node[len]);
}
for(sub_Type i=len-1;i>0;i--)
{
node_Type digit;
for(digit=myInt_size/10;digit>sign*node[i];digit/=10)
{
sprintf(ans,"%s0",ans);
}
if(node[i]!=0)
sprintf(ans,"%s%d",ans,sign*node[i]);
}
// printf("\n******in print function*****\n");
// for(int i=len;i>=1;i--)
// {
// printf("%d*",node[i]);
// }
// printf("\n***************\n");
printf("%s",ans);
return ;
}
//运算符重载
myInt operator + (const myInt &num_a,const myInt &num_b)
{
myInt ans;
for(sub_Type i=1;i<myInt_len;i++)
{
ans.node[i]=num_a.node[i]+num_b.node[i];
}
ans.carry();
return ans;
}
myInt operator - (const myInt &num_a,const myInt &num_b)
{
myInt ans;
for(sub_Type i=1;i<myInt_len;i++)
{
ans.node[i]=num_a.node[i]-num_b.node[i];
}
ans.carry();
return ans;
}
myInt operator * (const myInt &num_a,const myInt &num_b)
{
myInt ans;
for(sub_Type i=1;i<=num_a.len;i++)
{
for(sub_Type j=1;j<=num_b.len;j++)
{
ans.node[i+j-1]+=num_a.node[i]*num_b.node[j];
}
ans.carry();
}
return ans;
}
myInt operator / (const myInt &num_a,const myInt &num_b)
{
myInt quot,resi;
bool flag=myInt::myInt_Divid(num_a,num_b,quot,resi);
return quot;
}
myInt operator % (const myInt &num_a,const myInt &num_b)
{
myInt quot,resi;
bool flag=myInt::myInt_Divid(num_a,num_b,quot,resi);
return resi;
}
myInt & operator ++ (myInt & num)
{
return num=num+myInt(1);
}
myInt & operator -- (myInt & num)
{
return num=num-myInt(1);
}
myInt operator ++ (myInt & num,int u)
{
return num=num+myInt(1);
}
myInt operator -- (myInt & num,int u)
{
return num=num-myInt(1);
}
myInt & operator += (myInt &num_a,const myInt &num_b)
{
return num_a=num_a+num_b;
}
myInt & operator -= (myInt &num_a,const myInt &num_b)
{
return num_a=num_a-num_b;
}
myInt & operator *= (myInt &num_a,const myInt &num_b)
{
return num_a=num_a*num_b;
}
myInt & operator /= (myInt &num_a,const myInt &num_b)
{
return num_a=num_a/num_b;
}
myInt & operator %= (myInt &num_a,const myInt &num_b)
{
return num_a=num_a%num_b;
}
bool operator > (const myInt &num_a,const myInt &num_b)
{
int ans=myInt::myInt_Judge(num_a,num_b);
if(ans==1)
return true;
return false;
}
bool operator < (const myInt &num_a,const myInt &num_b)
{
int ans=myInt::myInt_Judge(num_a,num_b);
if(ans==-1)
return true;
return false;
}
bool operator >= (const myInt &num_a,const myInt &num_b)
{
int ans=myInt::myInt_Judge(num_a,num_b);
if(ans==1||ans==0)
return true;
return false;
}
bool operator <= (const myInt &num_a,const myInt &num_b)
{
int ans=myInt::myInt_Judge(num_a,num_b);
if(ans==0||ans==-1)
return true;
return false;
}
bool operator == (const myInt &num_a,const myInt &num_b)
{
int ans=myInt::myInt_Judge(num_a,num_b);
if(ans==0)
return true;
return false;
}
bool operator != (const myInt &num_a,const myInt &num_b)
{
int ans=myInt::myInt_Judge(num_a,num_b);
if(ans==1||ans==-1)
return true;
return false;
}
//类型转换
myInt::operator char*(void)
{
char* ans=(char*)malloc(myInt_len*size_Digit*sizeof(char));
if(sign==negative)
{
sprintf(ans,"-%d",sign*node[len]);
}
else
{
sprintf(ans,"%d",sign*node[len]);
}
for(sub_Type i=len-1;i>0;i--)
{
node_Type digit;
for(digit=myInt_size/10;digit>sign*node[i];digit/=10)
{
sprintf(ans,"%s0",ans);
}
if(node[i]!=0)
sprintf(ans,"%s%d",ans,sign*node[i]);
}
return ans;
}
myInt::operator int(void)
{
int ans=0;
for(sub_Type i=len;i>0;i--)
{
ans=ans*myInt_size+node[i];
}
return ans;
}
bool myInt::myInt_Divid(const myInt &num_a,const myInt &num_b,myInt ",myInt &resi)
{
if(num_b==myInt(0)) return false;
quot=myInt(0);
resi=num_a;
myInt nb=num_b;
if(nb.len>resi.len)
{
return true;
}
for(sub_Type i=1;i<=resi.len;i++) resi.node[i]=resi.node[i]*resi.sign;
for(sub_Type i=1;i<=nb.len;i++) nb.node[i]=nb.node[i]*nb.sign;
nb.sign=resi.sign=positive;
myInt num[size_Digit+1];
node_Type u=1;
for(sub_Type j=1;j<=size_Digit;j++)
{
num[j]=nb*myInt(u);
u*=10;
}
for(sub_Type i=resi.len-nb.len;i>=0;i--)
{
u=myInt_size;
for(sub_Type j=size_Digit;j>=1;j--)
{
u/=10;
int flag=1;
while(flag==1)
{
flag==0;
for(sub_Type k=myInt_len-1;k-i>0;k--)
{
if(resi.node[k]>num[j].node[k-i])
{
flag=1;
break;
}
else if(resi.node[k]<num[j].node[k-i])
{
flag=-1;
break;
}
}
if(flag==1)
{
for(sub_Type k=myInt_len-1;k-i>0;k--)
{
resi.node[k]-=num[j].node[k-i];
}
resi.carry();
quot.node[i+1]+=u;
}
}
}
}
for(sub_Type i=1;i<myInt_len;i++)
{
if(resi.node[i]) resi.node[i]*=num_a.sign;
if(quot.node[i]) quot.node[i]*=num_a.sign*num_b.sign;
}
resi.carry();
quot.carry();//符号
return true;
}
int myInt::myInt_Judge(const myInt & num_a,const myInt & num_b)//比较函数
{
for(sub_Type i=myInt_len-1;i>0;i--)
{
if(num_a.node[i]>num_b.node[i])
{
return 1;
}
else if(num_a.node[i]<num_b.node[i])
{
return -1;
}
}
return 0;
}
bool myInt::carry(void)//进位函数
{
// printf("\n****first*******\n");
// for(int i=6;i>=1;i--)
// {
// printf("%d*",node[i]);
// }
// printf("\n***************\n");
sub_Type n_len=1;
for(sub_Type i=1;i<myInt_len;i++)//从低位到高位
{
if(node[i]>=myInt_size||-1*node[i]>=myInt_size)
{
if(i==myInt_len-1)
{
return false;
}
else
{
node[i+1]+=node[i]/myInt_size;
node[i]=node[i]%myInt_size;
}
}
if(node[i])
{
n_len=i;
}
}
// printf("\n****second****\n");
// for(int i=6;i>=1;i--)
// {
// printf("%d*",node[i]);
// }
// printf("\n***************\n");
int flag;
if(node[n_len]>=0) flag=1;
else flag=-1;
node[n_len]-=flag;
for(sub_Type i=n_len-1;i>0;i--)//从高位到低位
{
node[i]+=(myInt_size-1)*flag;
}
node[1]+=flag;
// printf("\n****third******\n");
// for(int i=5;i>=1;i--)
// {
// printf("%d*",node[i]);
// }
// printf("\n***************\n");
n_len=1;
for(sub_Type i=1;i<myInt_len;i++)//从低位到高位
{
if(node[i]>=myInt_size||-1*node[i]>=myInt_size)
{
if(i==myInt_len-1)
{
return false;
}
else
{
node[i+1]+=node[i]/myInt_size;
node[i]=node[i]%myInt_size;
}
}
if(node[i])
{
n_len=i;
}
else
{
node[i]=0;
}
}
// printf("\n*****final******\n");
// for(int i=5;i>=1;i--)
// {
// printf("%d*",node[i]);
// }
// printf("\n***************\n");
len=n_len;
if(node[n_len]>=0) sign=positive;
else sign=negative;
return true;
}
//构造函数
myInt::myInt(void)
{
len=1;
for(sub_Type i=0;i<myInt_len;i++)
{
node[i]=0;
}
return ;
}
myInt::myInt(node_Type num)
{
for(sub_Type i=0;i<myInt_len;i++)
{
node[i]=0;
}
node[1]=num;
carry();
return ;
}
myInt::myInt(const myInt& num)
{
len=num.len;
sign=num.sign;
for(sub_Type i=0;i<myInt_len;i++)
{
node[i]=num.node[i];
}
return ;
}
myInt::myInt(const char str[],int carry_Num=10,int head=0,int tail=-1)
{
sub_Type digit=0;
if(tail==-1) tail=strlen(str)-1;
// printf("\n%s,%d\n",str,tail);
if(str[head]=='-') sign=negative,digit++;
else sign=positive;
head+=digit;
sub_Type node_Top=(tail-head+1)/size_Digit;
if((tail-head+1)%size_Digit!=0) node_Top++;
for(sub_Type i=1;i<myInt_len;i++)
{
node[i]=0;
}
// printf("str=\'%c~%c\'node_top=%d\n",str[head],str[tail],node_Top);
digit=head;
for(sub_Type i=node_Top;i>0;i--)
{
if(digit>tail)
{
break;
}
sub_Type j=tail-digit+1-size_Digit*(i-1);
while(j>0)
{
j--;
for(sub_Type num=0;num<carry_Num&&tranStr_a[num]!='\0';num++)
{
if(str[digit]==tranStr_a[num]||str[digit]==tranStr_b[num])
{
// printf("i=%d:j=%d;node[%d]=%d:num=%d,str[%d]=%c,a[%d]=%c,b[%d]=%c\n",i,j,i,node[i],num,digit,str[digit],num,tranStr_a[num],num,tranStr_b[num]);
node[i]=node[i]*10+sign*num;
break;
}
}
digit++;
}
// printf("i=%d;node[%d]=%d\n",i,i,node[i]);
}
carry();
// printf("\n***************\n");
// for(int i=len;i>=1;i--)
// {
// printf("%d*",node[i]);
// }
// printf("\n***************\n");
return;
}
#endif