其他分享
首页 > 其他分享> > 封装高精度整数模板(Bigint): +加 -减 *乘 /除 %模 (带一点点解释)

封装高精度整数模板(Bigint): +加 -减 *乘 /除 %模 (带一点点解释)

作者:互联网

本代码支持:
重载运算符 + - * / %
正负整数(%没有)
全高精度

我菜狗我直接放代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
namespace Bigint{
	const int maxn=2e4+2;
	struct bigint{
		int len,       a[maxn]; bool symbol;
		//  数字长度, 数字,        符号
        
		//初始化
		bigint(int x=0)
		{
			if(x>=0) symbol=true;
			else 	 symbol=false,x=-x;
			memset(a,0,sizeof(a));
			for(len=1;x;++len)
			{
				a[len]=x%10,
				x/=10;
			}
			--len;
		}
		//重载运算符[],使调用数位更方便
		int &operator [](int i)
		{
			return a[i];
		}
		//字符串输入(当然,也可以用快读读入string)
		void in()
		{
			string s;
			cin>>s;
			len=s.size();
			for(int i=len-1;i>=1;--i)
			{
				a[len-i]=s[i]-'0';
			}
			if(s[0]=='-') symbol=false,--len;
			else a[len]=s[0]-'0';
		}
		//进位并去除前导0
		void flatten(int l)
		{
			len=l;
			for(int i=1;i<=len;++i)
			{
				a[i+1]+=a[i]/10;
				a[i]%=10;
			}
			for(;!a[len];--len);
		}
		//借位(?并实现前导0
		//减法最后再借位也不是不行,只要借的到
		void flatten_(int l)
		{
			len=l;
			for(int i=1;i<=len;++i)
			{
				if(a[i]<0)
				{
					--a[i+1],
					a[i]+=10;
				}
			}
			for(;!a[len];--len);
		}
		//输出
		void out()
		{
			if(!symbol&&len>=1) printf("-");//还要防止出现-0
			for(int i=max(len,1);i>=1;--i)
			{
				printf("%d",a[i]);
			}
		}
	};
	
	bool compare(bigint x,bigint y)
	{
		//If x>=y,return true.
		bool flag=true;
		if(x.len<y.len) return false;
		else
		if(x.len==y.len)
		{
			for(int i=x.len;i>=1;--i)
			{
				if(y[i]<x[i]) return true;
				if(y[i]>x[i]) return false;
			}
		}
		return true;
	}
	
	bigint plus(bigint x,bigint y)// '+'
	{
		bigint res;
		res.len=max(x.len,y.len);
		for(int i=1;i<=res.len;++i)
		{
			res[i]+=x[i]+y[i];
//			等价于 res.a[i]+=a.a[i]+b.a[i];
//			这就是重载[]的作用了
		}
		res.flatten(res.len+1);
		return res;
	}
	bigint minus(bigint x,bigint y)// '*'
	{
		bigint res;
		res.len=x.len;
		for(int i=1;i<=res.len;++i)
		{
			res[i]+=x[i]-y[i];
		}
		res.flatten_(res.len);
		return res;
	}
	bigint multiply(bigint x,bigint y)// '*'
	{
		bigint res;int len=x.len+y.len;
		for(int i=1;i<=x.len;++i)
		{
			for(int j=1;j<=y.len;++j)
			{
				res[i+j-1]+=x[i]*y[j];
			}
		}
		res.flatten(len+1);
		return res;
	}
	bigint divide_by(bigint x,bigint y)// '/'
	{
		//The division based on subtraction.
		//懒得打试除法了,直接用减法一点点减
		bigint res;res.len=x.len;
		for(int tail=x.len-y.len;tail>=0;--tail)
		{
			while(true)
			{
				bool flag=false;
				for(int i=y.len;i>=1;--i)
				{
					if(x[i+tail]>y[i]) break;
					if(x[i+tail]<y[i])
					{
						flag=true;
						break;
					}
				}
				if(flag) break;
				for(int i=y.len;i>=1;--i)
				{
					x[i+tail]-=y[i];
				}
				++res[tail+1];
				x.flatten_(x.len);
			}
			x[y.len+tail-1]+=x[y.len+tail]*10;
			x[y.len+tail]=0;
		}
		res.flatten(res.len);
		return res;
	}
	bigint mod_by(bigint x,bigint y)// '%'
	{
		int len=x.len;
		for(int tail=x.len-y.len;tail>=0;--tail)
		{
			while(true)
			{
				bool flag=false;
				for(int i=y.len;i>=1;--i)
				{
					if(x[i+tail]>y[i]) break;
					if(x[i+tail]<y[i])
					{
						flag=true;
						break;
					}
				}
				if(flag) break;
				for(int i=y.len;i>=1;--i)
				{
					x[i+tail]-=y[i];
				}
				x.flatten_(x.len);
			}
			x[y.len+tail-1]+=x[y.len+tail]*10;
			x[y.len+tail]=0;
		}
		x.flatten_(len+1);
		x.flatten(len+1);
		return x;//返回剩下的就是余数了
	}
	
	//以上操作只适用于正整数,对正负的判断在下面的重载函数中
    
	bigint operator -(bigint x,bigint y)
	{
		bigint res;
		if(compare(x,y)) res=minus(x,y);
		else			 res=minus(y,x),res.symbol=false;
		return res;
	}
	//O(len)
	
	bigint operator +(bigint x,bigint y)
	{
		if(x.symbol&&!y.symbol) return x-y;
		if(!x.symbol&&y.symbol) return y-x;
		if(!x.symbol)
		{
			bigint res;
			res=plus(x,y),
			res.symbol=false;
			return res;
		}
		return plus(x,y);
	}
	//O(len)
	
	bigint operator *(bigint x,bigint y)
	{
		bigint res;
		res=multiply(x,y);
		if(x.symbol^y.symbol) res.symbol=false;
		return res;
	}
	//O(len^2)
	
	bigint operator /(bigint x,bigint y)
	{
		bigint res;
		res=divide_by(x,y);
		if(x.symbol^y.symbol) res.symbol=false;
		return res;
	}
	//O(len^2)
	
	bigint operator %(bigint x,bigint y)
	{
		//Only positive number.
		return mod_by(x,y);
	}
	//O(len^2)
}
using namespace Bigint;
bigint a,b,c;
signed main()
{
//	a.in();b.in();
//	c=a+b;
//	c.out();puts("");
//	c=a-b;
//	c.out();puts("");
//	c=a*b;
//	c.out();puts("");
//	c=a/b;
//	c.out();puts("");
//	c=a%b;
//	c.out();puts("");
	return 0;
}

%的只是把除法代码改了下。。

实测可过 洛谷:P1932 A+B A-B A*B A/B A%B Problem

毕竟花了一整天还多。。今天想争取把浮点数搞定。

标签:封装,int,res,bigint,len,tail,Bigint,return,模板
来源: https://blog.csdn.net/weixin_45488021/article/details/122875054