高精度整型模板

高精度整型模板

一直想写一个这样的模板,但奈何本人比较 菜。。。
说明都在注释里。
行数有点多,说明主要集中在开头了。
和传统的高精有点区别,这个大概可以当做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 &quot,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 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值