__int1024!(C++高精度便捷模板)

使用说明:

  1. 数据范围约为\(-2^{1024}\le N \le2^{1024}\),反映到十进制约为\(-10^{309}\le N \le10^{309}\),但不保证完全如此。
  2. 输入输出使用自带的输入及输出函数。由于其内部用scanfprintf来实现,所以请不要把它与ios::sync_with_stdio(false)同时使用。
  3. 由于内部采用高精度实现,所以复杂度不可忽略。具体复杂度会在下面列出,\(m\)\(n\)分别为两个数字的位数。
  4. 特别地,自增及自减运算只能放在变量前面。如置于后面会报错。例:++a
  5. 特别地,如果你要给一个__int1024付初值的话,请调用.zp并赋一个字符串。
    支持操作:
  6. 输入输出。使用.in().out()即可。
  7. 运算。支持+ O(n)- O(n)* O(mn)/ O(mnlog10)% O(mn(m+log10+1))++ O(n)-- O(n)共七种运算,类比int使用即可。
  8. 赋值。直接使用=即可。
  9. 比较关系。支持>>=<<===!=共六种运算(都是\(O(n)\)),类比int使用即可。
    头文件&宏定义:
    宏定义不喜可换。
#include<iostream>
#include<string.h>
using namespace std;
#define il inline
#define ri register int

正片:
因为本来就没想让别人读懂所以一点注释都没加。

struct __int1024
{
	#define N 310
	string zp;
	il void out()
	{
		int h=0;
		if(zp[h]=='-')
		{
			printf("%c",zp[h]);
			h++;
		}
		while(zp[h]>='0'&&zp[h]<='9')
		{
			printf("%c",zp[h]);
			h++;
		}
		return;
	}
	il void in()
	{
		char c=getchar(),op='+';
		while(c<'0'||c>'9')
		{
			if(c=='-')
			{
				op='-';
			}
		}
		if(op=='-')
		{
			zp.push_back(op);
		}
		while(c>='0'&&c<='9')
		{
			zp.push_back(c);
			c=getchar();
			continue;
		}
		return;
	}
	il bool dayu(__int1024 x,__int1024 y)
	{
		if(x.zp[0]=='-'&&y.zp[0]=='-')
		{
			__int1024 m,n;
			int u=x.zp.size(),v=x.zp.size();
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			return dayu(n,m);
		}
		if(x.zp[0]=='-')
		{
			return false;
		}
		if(y.zp[0]=='-')
		{
			return true;
		}
		if(x.zp.size()>y.zp.size())
		{
			return true;
		}
		if(x.zp.size()<y.zp.size())
		{
			return false;
		}
		for(ri i=0;i<x.zp.size();i++)
		{
			if(x.zp[i]>y.zp[i])
			{
				return true;
			}
			if(x.zp[i]<y.zp[i])
			{
				return false;
			}
		}
		return false;
	}
	il bool xiaoyu(__int1024 x,__int1024 y)
	{
		if(x.zp[0]=='-'&&y.zp[0]=='-')
		{
			__int1024 m,n;
			int u=x.zp.size(),v=x.zp.size();
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			return xiaoyu(n,m);
		}
		if(x.zp[0]=='-')
		{
			return true;
		}
		if(y.zp[0]=='-')
		{
			return false;
		}
		if(x.zp.size()<y.zp.size())
		{
			return true;
		}
		if(x.zp.size()>y.zp.size())
		{
			return false;
		}
		for(ri i=0;i<x.zp.size();i++)
		{
			if(x.zp[i]<y.zp[i])
			{
				return true;
			}
			if(x.zp[i]>y.zp[i])
			{
				return false;
			}
		}
		return false;
	}
	il bool dengyu(__int1024 x,__int1024 y)
	{
		if(x.zp.size()!=y.zp.size())
		{
			return false;
		}
		for(ri i=0;i<x.zp.size();i++)
		{
			if(x.zp[i]!=y.zp[i])
			{
				return false;
			}
		}
		return true;
	}
	il __int1024 jia(__int1024 x,__int1024 y)
	{
		string rn;
		__int1024 qm;
		int u=x.zp.size(),v=y.zp.size(),w;
		if(x.zp[0]=='-'&&y.zp[0]=='-')
		{
			__int1024 m,n,z;
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			z=jia(m,n);
			if(z.zp[0]=='-')
			{
				rn=z.zp.substr(1,z.zp.size()-1);
			}
			else
			{
				rn.resize(1,'-');
				rn+=z.zp;
			}
			qm.zp=rn;
			return qm;
		}
		if(x.zp[0]=='-')
		{
			__int1024 z;
			z.zp=x.zp.substr(1,u-1);
			return jian(y,z);
		}
		if(y.zp[0]=='-')
		{
			__int1024 z;
			z.zp=y.zp.substr(1,v-1);
			return jian(x,z); 
		}
		int o[N],p[N],q[N];
		memset(o,0,sizeof(o));
		memset(p,0,sizeof(p));
		memset(q,0,sizeof(q));
		for(ri i=0,j=u;j>0;i++,j--)
		{
			p[j]=x.zp[i]-'0';
		}
		for(ri i=0,j=v;j>0;i++,j--)
		{
			q[j]=y.zp[i]-'0';
		}
		w=max(u,v);
		for(ri i=1;i<=w+1;i++)
		{
			int j=p[i]+q[i];
			o[i]+=j;
			o[i+1]+=o[i]/10;
			o[i]%=10;
		}
		if(o[w+1]!=0)
		{
			w++;
		}
		rn.resize(w,'0');
		for(ri i=0,j=w;j>0;i++,j--)
		{
			rn[i]+=o[j];
		}
		qm.zp=rn;
		return qm;
	}
	il __int1024 jian(__int1024 x,__int1024 y)
	{
		__int1024 qm;
		string rn;
		int u=x.zp.size(),v=y.zp.size(),w;
		if(x.zp[0]=='-'&&y.zp[0]=='-')
		{
			__int1024 m,n,z;
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			z=jian(m,n);
			w=z.zp.size();
			if(z.zp[0]=='-')
			{
				rn=z.zp.substr(1,w-1);
			}
			else
			{
				rn.resize(1,'-');
				rn+=z.zp;
			}
			qm.zp=rn;
			return qm;
		}
		if(y.zp[0]=='-')
		{
			__int1024 z;
			z.zp=y.zp.substr(1,v-1);
			return jia(x,z);
		}
		if(x.zp[0]=='-')
		{
			__int1024 z,t;
			z.zp=x.zp.substr(1,u-1);
			t=jia(z,y);
			qm.zp.resize(1,'-');
			qm.zp+=t.zp;
			return qm;
		}
		if(dayu(x,y)==false&&dengyu(x,y)==false)
		{
			__int1024 m,n,z;
			m.zp=x.zp;
			n.zp=y.zp;
			z=jian(n,m);
			w=z.zp.size();
			if(z.zp[0]=='-')
			{
				rn=z.zp.substr(1,w-1);
			}
			else
			{
				rn.resize(1,'-');
				rn+=z.zp;
			}
			qm.zp=rn;
			return qm;
		}
		int o[N],p[N],q[N];
		memset(o,0,sizeof(o));
		memset(p,0,sizeof(p));
		memset(q,0,sizeof(q));
		for(ri i=0,j=u;j>0;i++,j--)
		{
			p[j]=x.zp[i]-'0';
		}
		for(ri i=0,j=v;j>0;i++,j--)
		{
			q[j]=y.zp[i]-'0';
		}
		for(ri i=1;i<=u;i++)
		{
			int j=p[i]-q[i];
			o[i]+=j;
			o[i+1]+=o[i]/10;
			o[i]%=10;
			if(o[i]<0)
			{
				o[i]+=10;
				o[i+1]-=1;
			}
		}
		while(o[u]==0&&u!=1)
		{
			u--;
		}
		rn.resize(u,'0');
		for(ri i=0,j=u;j>0;i++,j--)
		{
			rn[i]+=o[j];
		}
		qm.zp=rn;
		return qm;
	}
	il __int1024 cheng(__int1024 x,__int1024 y)
	{
		string rn;
		__int1024 qm;
		int u=x.zp.size(),v=y.zp.size(),w;
		if(x.zp[0]=='-'&&y.zp[0]=='-')
		{
			__int1024 m,n;
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			return cheng(m,n);
		}
		if(x.zp[0]=='-'||y.zp[0]=='-')
		{
			__int1024 m,n,z;
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			z=cheng(m,n);
			if(z.zp[0]=='-')
			{
				rn=z.zp.substr(1,z.zp.size()-1);
			}
			else
			{
				rn.resize(1,'-');
				rn+=z.zp;
			}
			qm.zp=rn;
			return qm;
		}
		int o[N],p[N],q[N];
		memset(o,0,sizeof(o));
		memset(p,0,sizeof(p));
		memset(q,0,sizeof(q));
		for(ri i=0,j=u;j>0;i++,j--)
		{
			p[j]=x.zp[i]-'0';
		}
		for(ri i=0,j=v;j>0;i++,j--)
		{
			q[j]=y.zp[i]-'0';
		}
		w=u+v;
		for(ri i=1;i<=u;i++)
		{
			for(ri j=1;j<=v;j++)
			{
				int k=p[i]*q[j];
				o[i+j-1]+=k;
				o[i+j]+=o[i+j-1]/10;
				o[i+j-1]%=10;
			}
		}
		while(o[w]==0&&w!=1)
		{
			w--;
		}
		rn.resize(w,'0');
		for(ri i=0,j=w;j>0;i++,j--)
		{
			rn[i]+=o[j];
		}
		qm.zp=rn;
		return qm;
	}
	il __int1024 chu(__int1024 x,__int1024 y)
	{
		string rn;
		__int1024 qm;
		int u=x.zp.size(),v=y.zp.size();
		if(x.zp[0]=='-'&&y.zp[0]=='-')
		{
			__int1024 m,n;
			m.zp=x.zp.substr(1,u-1);
			n.zp=y.zp.substr(1,v-1);
			return chu(m,n);
		}
		if(x.zp[0]=='-')
		{
			__int1024 m,z;
			m.zp=x.zp.substr(1,u-1);
			z=chu(m,y);
			if(z.zp[0]=='-')
			{
				rn=z.zp.substr(1,z.zp.size()-1);
			}
			else
			{
				rn.resize(1,'-');
				rn+=z.zp;
			}
			qm.zp=rn;
			return qm;
		}
		if(y.zp[0]=='-')
		{
			__int1024 n,z;
			n.zp=y.zp.substr(1,v-1);
			z=chu(x,n);
			if(z.zp[0]=='-')
			{
				rn=z.zp.substr(1,z.zp.size()-1);
			}
			else
			{
				rn.resize(1,'-');
				rn+=z.zp;
			}
			qm.zp=rn;
			return qm;
		}
		if(dayu(x,y)==false&&dengyu(x,y)==false)
		{
			qm.zp="0";
			return qm;
		}
		int o[N],p[N],q[N];
		memset(o,0,sizeof(o));
		memset(p,0,sizeof(p));
		memset(q,0,sizeof(q));
		for(ri i=0;i<u;i++)
		{
			p[i+1]=x.zp[i]-'0';
		}
		for(ri i=0;i<u;i++)
		{
			q[i+1]=y.zp[i]-'0';
		}
		int rt=1;
		for(ri i=1;i<=u;i++)
		{
			if(rt>i)
			{
				o[i]=0;
				continue;
			}
			string al=x.zp.substr(0,i-rt+1);
			__int1024 z;
			z.zp=al;
			if(dayu(y,z)==true)
			{
				o[i]=0;
				continue;
			}
			int m=1,n=9;
			while(n-m>1)
			{
				char l=((m+n)>>1)+'0';
				__int1024 wn;
				wn.zp.push_back(l);
				if(dayu(cheng(y,wn),z)==true)
				{
					n=l-'0'-1;
				}
				else
				{
					m=l-'0';
				}
			}
			char l=n+'0';
			__int1024 wn,xo;
			wn.zp.push_back(l);
			if(dayu(cheng(y,wn),z)==false)
			{
				o[i]=n;
				wn.zp[0]=n+'0';
				xo=cheng(wn,y);
				for(ri j=i+1;j<=u;j++)
				{
					xo.zp.push_back('0');
				}
				int sk=x.zp.size();
				x=jian(x,xo);
				rt+=sk-x.zp.size();
			}
			else
			{
				o[i]=m;
				wn.zp[0]=m+'0';
				xo=cheng(wn,y);
				for(ri j=i+1;j<=u;j++)
				{
					xo.zp.push_back('0');
				}
				int sk=x.zp.size();
				x=jian(x,xo);
				rt+=sk-x.zp.size();
			}
		}
		int w=1;
		while(o[w]==0&&w!=u)
		{
			w++;
		}
		rn.resize(u-w+1,'0');
		for(ri i=0,j=w;j<=u;i++,j++)
		{
			rn[i]+=o[j];
		}
		qm.zp=rn;
		return qm;
	}
	__int1024 zjia(__int1024 x)
	{
		string rn;
		if(x.zp[0]=='-')
		{
			__int1024 y,z;
			y.zp=x.zp.substr(1,x.zp.size());
			z=zjian(y);
			if(z.zp[0]!='0')
			{
				rn=z.zp;
				z.zp='-';
				z.zp+=rn;
			}
			return z;
		}
		int h=x.zp.size()-1;
		while(x.zp[h]=='9'&&h>=0)
		{
			x.zp[h]='0';
			h--;
		}
		if(h<0)
		{
			rn=x.zp;
			x.zp='1';
			x.zp+=rn;
		}
		else
		{
			x.zp[h]+=1;
		}
		return x;
	}
	__int1024 zjian(__int1024 x)
	{
		string rn;
		if(x.zp[0]=='0')
		{
			x.zp="-1";
			return x;
		}
		if(x.zp[0]=='-')
		{
			__int1024 y,z;
			y.zp=x.zp.substr(1,x.zp.size());
			z=zjia(y);
			if(z.zp[0]!='0')
			{
				rn=z.zp;
				z.zp='-';
				z.zp+=rn;
			}
			return z;
		}
		int h=x.zp.size()-1;
		while(x.zp[h]=='0'&&h>=0)
		{
			x.zp[h]='9';
			h--;
		}
		if(h<0)
		{
			rn=x.zp.substr(1,x.zp.size()-1);
			x.zp+=rn;
		}
		else
		{
			x.zp[h]-=1;
		}
		return x;
	}
	__int1024 operator +(const __int1024 &A)
	{
		return jia(*this,A);
	}
	__int1024 operator -(const __int1024 &A)
	{
		return jian(*this,A);
	}
	__int1024 operator*(const __int1024 &A)
	{
		return cheng(*this,A);
	}
	__int1024 operator/(const __int1024 &A)
	{
		return chu(*this,A);
	}
	__int1024 operator%(const __int1024 &A)
	{
		return jian(*this,cheng(A,chu(*this,A)));
	}
	void operator++()
	{
		*this=zjia(*this);
	}
	void operator--()
	{
		*this=zjian(*this);
	}
	void operator =(const __int1024 &A)
	{
		zp=A.zp;
		return;
	}
	bool operator >(const __int1024 &A)
	{
		return dayu(*this,A);
	}
	bool operator <(const __int1024 &A)
	{
		return xiaoyu(*this,A);
	}
	bool operator ==(const __int1024 &A)
	{
		return dengyu(*this,A);
	}
	bool operator >=(const __int1024 &A)
	{
		return (dayu(*this,A)||dengyu(*this,A));
	}
	bool operator <=(const __int1024 &A)
	{
		return (xiaoyu(*this,A)||dengyu(*this,A));
	}
	bool operator !=(const __int1024 &A)
	{
		return (dengyu(*this,A)==true)?false:true;
	}
	#undef N
};

后记:
想学高精建议打P1932
__int65536正加紧制作中!

posted @ 2024-06-18 12:18  一位很会的教授er~  阅读(280)  评论(3编辑  收藏  举报