高精度。。

本文介绍了一个高精度数值计算类的实现细节,包括加、减、乘、除等基本运算,以及比较、取余等操作。该类支持非常大的整数运算,进制可在2至10000间调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

高精度类。。可进行有符号加减乘除取余。。以及+-*/%<<>>==><运算符。。可修改进制(2到10000)。。

#define refcnt(a) while((a).cells[(a).ccount]==0&&(a).ccount>0)(a).ccount--;
const int cellcount=1100,cellwidth=1;//精确到cellcount*cellwidth位
int base=10;//进制
struct bigint
{
	int cells[cellcount+1];
	int ccount;
	bool op;
	bigint()
	{
		op=true;
		memset(cells,0,sizeof(cells));
		ccount=0;
	}
	bigint(int v)
	{
		op=true;
		if(v<0){v=-v;op=false;}
		memset(cells,0,sizeof(cells));
		cells[0]=v;
		ccount=0;
		while(cells[ccount]>=base){
			cells[ccount+1]=cells[ccount]/base;
			cells[ccount]%=base;
			ccount++;
		}
	}
	inline void _parse(char* ch,int p,int& cp)
	{
		for(int i=p;i<p+cellwidth;i++)
			cp=cp*10+ch[i]-'0';
	}
	void parse(char* ch)
	{
		if(ch[0]=='-'){
			op=false;
			ch++;
		}else
			op=true;
		int l=strlen(ch);
		int i,j,k;
		for(i=l-cellwidth,j=0;i>=0;i-=cellwidth)
			_parse(ch,i,cells[j++]);
		if(i!=-cellwidth){
			for(k=0;k<i+cellwidth;k++)
				cells[j]=cells[j]*10+ch[k]-'0';
			ccount=j;
		}
		else ccount=j-1;
	}
	friend istream& operator>>(istream& stream,bigint& num)
	{
		char buff[10000];
		stream>>buff;
		memset(num.cells,0,sizeof(int)*(num.ccount+1));
		num.ccount=0;
		num.parse(buff);
		return stream;
	}
	void output(char* res) const
	{
		char* r=res;
		if(!op&&(ccount!=0||cells[0]!=0))*(res++)='-';
		sprintf(res,"%d",cells[ccount]);
		res+=strlen(res);
		char format[5]="%00d";
		format[2]='0'+cellwidth;
		for(int i=ccount-1;i>=0;i--){
			sprintf(res,format,cells[i]);
			res+=cellwidth;
		}
		res=r;
	}
	friend ostream& operator<<(ostream& stream,const bigint& num)
	{
		char buff[cellcount*cellwidth+1];
		num.output(buff);
		stream<<buff;
		return stream;
	}
	
	inline static int cmp(const bigint& a,const bigint& b,bool ignore=false)
	{
		int r=1;
		if(!ignore){
			if(a.op^b.op)return a.op?1:-1;
			if(!(a.op^b.op)&&!a.op) r=-1;
		}
		if(a.ccount>b.ccount)return r;
		else if(a.ccount<b.ccount)return -r;
		else
		{
			for(int i=a.ccount;i>=0;i--){
				if(a.cells[i]>b.cells[i])return r;
				else if(a.cells[i]<b.cells[i])return -r;
			}
		}
		return 0;
	}
	bool operator <(const bigint& a) const
	{
		return cmp(*this,a)<0;
	}
	bool operator >(const bigint& a) const
	{
		return cmp(*this,a)>0;
	}
	bool operator ==(const bigint& a) const
	{
		return cmp(*this,a)==0;
	}
	
	inline static void getplus(bigint& res,const bigint& a,const bigint& b,bool op=true)
	{
		res.op=op;
		int up=0;
		int tmp;
		res.ccount=min(max(a.ccount,b.ccount)+1,cellcount);
		memset(res.cells,0,sizeof(res.cells));
		for(int i=0;i<res.ccount;i++)
		{
			res.cells[i]=(tmp=res.cells[i]+a.cells[i]+b.cells[i])%base;
			res.cells[i+1]=tmp/base;
		}
		refcnt(res);
	}
	inline static void getminus(bigint& res,const bigint& a,const bigint& b,bool op=true)
	{
		if(cmp(a,b,true)<0){
			getminus(res,b,a,!op);return;}
		res.op=op;
		int up=0;
		int tmp;
		res.ccount=a.ccount;
		memset(res.cells,0,sizeof(res.cells));
		for(int i=0;i<=res.ccount;i++)
		{
			if((tmp=res.cells[i]+a.cells[i]-b.cells[i])<0){tmp+=base;res.cells[i+1]--;}
			res.cells[i]=tmp;
		}
		refcnt(res);
	}
	inline static void getmultiply(bigint& res,const bigint& a,const bigint& b,int offset=0)
	{
		res.op=!(a.op^b.op);
		int up=0;
		int tmp;
		res.ccount=min(a.ccount+b.ccount+1+offset,cellcount);
		memset(res.cells,0,sizeof(res.cells));
		for(int i=0;i<=a.ccount;i++)
			for(int j=0;j<=b.ccount;j++)
			{
				if(i+j+offset>=cellcount)break;
				res.cells[i+j+offset]=(tmp=res.cells[i+j]+a.cells[i]*b.cells[j])%base;
				res.cells[i+j+1+offset]+=tmp/base;
			}
		refcnt(res);
	}
	inline static void getmultiply(bigint&res,const bigint&a,int b,int offset=0)
	{
		res.op=a.op;
		if(b<0){res.op=!res.op;b=-b;}
		int up=0;
		int tmp=0;
		int i;
		memset(res.cells,0,sizeof(res.cells));
		for(i=0;i<=a.ccount||tmp!=0;i++)
		{
			if(i+offset>=cellcount)break;
			res.cells[i+offset]=(tmp=res.cells[i+offset]+a.cells[i]*b)%base;
			res.cells[i+1+offset]=tmp/base;
		}
		res.ccount=i+offset;
		refcnt(res);
	}
	bigint operator -() const
	{
		bigint res=*this;
		if(cells[0]==0&&ccount==0)return res;
		else {
			res.op=!res.op;
			return res;
		}
	}
	bigint operator +(const bigint& a) const
	{
		bigint res(0);
		if(!(op^a.op))
			getplus(res,*this,a,op);
		else
			getminus(res,*this,a,op);
		return res;
	}
	bigint operator -(const bigint& a) const
	{
		bigint res(0);
		if(!(a.op^op))
			getminus(res,*this,a,op);
		else
			getplus(res,*this,a,op);
		return res;
	}
	bigint operator *(const bigint& a) const
	{
		bigint res(0);
		getmultiply(res,*this,a);
		return res;
	}
	bigint operator *(int a) const
	{
		bigint res;
		getmultiply(res,*this,a);
		return res;
	}
	inline static void tryminus(bigint& res,bigint& a,const bigint& b)
	{
		int ai,bi=b.cells[b.ccount],pre=a.ccount-b.ccount;
		if(a.cells[a.ccount]>b.cells[b.ccount])ai=a.cells[a.ccount]/(b.cells[b.ccount]+1);
		else{
			if(a.ccount==b.ccount&&a.cells[a.ccount]==b.cells[b.ccount]){
				res.cells[0]++;
				a=a-b;
				return;
			}
			ai=(a.cells[a.ccount]*base+a.cells[a.ccount-1])/(b.cells[b.ccount]+1);
			pre--;
		}
		res.cells[pre]+=ai;
		bigint r;
		getmultiply(r,b,ai,pre);
		bigint an;
		getminus(an,a,r);
		a=an;
	}
	
	inline static void make(bigint& r)
	{
		refcnt(r);
		for(int i=0;i<=r.ccount;i++)
			if(r.cells[i]>=base)
			{
				r.cells[i+1]+=r.cells[i]/base;
				r.cells[i]%=base;
			}
		if(r.cells[r.ccount+1]>0)r.ccount++;
		while(r.cells[r.ccount]>=base&&r.ccount<=cellcount){
			r.cells[r.ccount+1]+=r.cells[r.ccount]/base;
			r.cells[r.ccount]%=base;
			r.ccount++;
		}
	}
	inline static bool getdevide(bigint& res,bigint& ys,const bigint& a,const bigint& b)
	{
		if(b.cells[0]==0&&b.ccount==0)return false;
		res.ccount=a.ccount;
		memset(res.cells,0,sizeof(res.cells));
		memcpy(&ys,&a,sizeof(bigint));
		while(true)
		{
			int c=cmp(ys,b,true);
			if(c<0)break;
			if(c==0){memset(&ys,0,sizeof(ys));res.cells[0]++;break;}
			else
			{
				tryminus(res,ys,b);
			}
		}
		make(res);
		return true;
	}
	bigint operator %(const bigint& a) const
	{
		bigint res,ys;
		getdevide(res,ys,*this,a);
		ys.op=op;
		return ys;
	}
	bigint operator /(const bigint& a) const
	{
		bigint res,ys;
		getdevide(res,ys,*this,a);
		res.op=!(op^a.op);
		return res;
	}

};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值