C++中高精度正整数运算代码模板

背景:

C++中有时我们会遇到(unsigned)long long也表示不了的大整数,这个时候我们常常会用高精度

为了简化使用过程以及模板化,我们不妨用struct或class来定义

详解:

框架:

template<int SIZE>//用来限制最大表示位数 
class bign(){
  private://在class外不能调用 
	int a[SIZE],len;//高精度整数,用数组表示 
  public:
	//一系列运算函数 
} 

输入输出:

    bign(){len=1;memset(a,0,sizeof(a));}//初始化
    void in(){
    	char s[SIZE];
    	scanf("%s",s);
	len=strlen(s);
	for(int i=0,j=len-1;i<len;i++,j--) a[i]=s[j]-48;
	while(len>1&&a[len-1]==0) len--;//应对输入含前导0 
    }
    void out(bool Entr=true){//默认输出换行 
	for(int i=len-1;i>=0;i--) putchar(a[i]+'0');
	if(Entr) putchar('\n');
    }

赋值:

这部分主要是模拟实现,就不加注释了。相当于小学算数,自己思考一下

	void operator = (char *s){
		len=strlen(s);
		for(int i=0,j=len-1;i<len;i++,j--) a[i]=s[j]-48;
		while(len>1&&a[len-1]==0) len--;
	}
	void operator = (int x){
		len=0;if(x==0) len=1,a[0]=0;
		while(x>0) a[len++]=x%10,x/=10;
	}
	void operator = (long long x){
		len=0;if(x==0) len=1,a[0]=0;
		while(x>0) a[len++]=x%10,x/=10;
	}

大小比较:

	friend bool operator < (bign a,bign b){
		if(a.len!=b.len) return a.len<b.len;
		for(int i=a.len-1;i>=0;i--)
			if(a.a[i]!=b.a[i]) return a.a[i]<b.a[i];
		return false;//表示a,b相等 
	}
	friend bool operator > (bign a,bign b){
		return b<a;
	}
	friend bool operator <= (bign a,bign b){
		return !(a>b);
	}
	friend bool operator >= (bign a,bign b){
		return !(a<b);
	}
	friend bool operator == (bign a,bign b){
		return !(a>b&&b<a);
	}
	friend bool operator != (bign a,bign b){
		return a<b||b<a;
	}

加减乘除运算:

	friend bign operator + (bign a,bign b){
		bign c;
		int lenth=max(a.len,b.len)+1;
		for(int i=0;i<lenth;i++) c.a[i]=a.a[i]+b.a[i];
		for(int i=0;i<lenth;i++){
			if(c.a[i]>9) c.a[i]-=10,c.a[i+1]++;
		}
		while(lenth>1&&c.a[lenth-1]==0) lenth--;
		c.len=lenth;
		return c;
	}
	friend bign operator - (bign a,bign b){//求a-b的绝对值 
		bign c;
		if(a<b) swap(a,b);
		int len=a.len;
		for(int i=0;i<len;i++)
			c.a[i]=a.a[i]-b.a[i];
		for(int i=0;i<len;i++)
			if(c.a[i]<0) c.a[i+1]--, c.a[i]+=10;
		while(len>1&&c.a[len-1]==0) len--;
		c.len=len;
		return c;
	}
	friend bign operator * (bign a,bign b){
		bign ans;
		int len=a.len+b.len;
		for(int i=0;i<a.len;i++)
			for(int j=0;j<b.len;j++)
				ans.a[i+j]+=a.a[i]*b.a[j];//这里要思考一下 
		for(int i=0;i<len;i++)
			if(ans.a[i]>9) ans.a[i+1]+=ans.a[i]/10,ans.a[i]%=10;
		while(len>1&&ans.a[len-1]==0) len--;
		ans.len=len;
		return ans;
	}
	friend bign operator * (bign a,int x){//防溢出,x<=200,000,000 
		bign ans;
		int len=a.len+20;
		for(int i=0;i<len;i++) ans.a[i]=a.a[i]*x;
		for(int i=0;i<len;i++)
			if(ans.a[i]>9) ans.a[i+1]+=ans.a[i]/10,ans.a[i]%=10;
		while(ans.a[len-1]==0&&len>1) len--;
		ans.len=len;
		return ans;
	}
	friend bign operator / (bign a,int b){//防溢出 
		bign c;
		int d=0,len=a.len;
		for(int i=len-1;i>=0;i--)
			d=d*10+a.a[i],c.a[i]=d/b,d=d%b;
		while(len>1&&c.a[len-1]==0) len--;
		c.len=len;
		return c;
	}
	friend bign operator / (bign a,bign b){
		bign c,d;
		int len=a.len;
		for(int i=len-1;i>=0;i--){
			d=d*10;
			d.a[0]=a.a[i];
			while(d>=b) c.a[i]++, d=d-b;//这里效率不是很高 
		}
		while(len>1&&c.a[len-1]==0) len--;
		c.len=len;
		return c;
	}

取模:

	friend int operator % (bign a,int b){//注意返回值为int 
		int d=0,len=a.len;
		for(int i=len-1;i>=0;i--)
			d=d*10+a.a[i],d=d%b;
		return d;
	}
	friend bign operator % (bign a,bign b){
		bign d;
		int len=a.len;
		for(int i=len-1;i>=0;i--){
			d=d*10;
			d.a[0]=a.a[i];
			while(d>=b) d=d-b;//同理,效率不够高 
		}
		while(len>1&&d.a[len-1]==0) len--;
		d.len=len;
		return d;
	}

部分扩展功能:

	friend bign gcd(bign a,bign b){//求最大公约数 
		bign zero;
		zero=0;
		return b==zero?a:gcd(b,a%b);
	}
	friend bign pow_mod(int a,int n,bign m){//求a^n mod m (m为高精度数) 
		bign ret,X;
		if(n==0){
			ret=1;return ret;
		}
		X=pow_mod(a,n/2,m);
		ret=(X*X)%m;
		if(n%2) ret=(ret*a)%m;
		return ret;
	}

完整代码:

template<int SIZE>
class bign{
  private:
	int a[SIZE],len;
  public:
	bign(){len=1;memset(a,0,sizeof(a));}
	void in(){
		char s[SIZE];
		scanf("%s",s);
		len=strlen(s);
		for(int i=0,j=len-1;i<len;i++,j--) a[i]=s[j]-48;
		while(len>1&&a[len-1]==0) len--;
	}
	void out(bool Entr=true){
		for(int i=len-1;i>=0;i--) putchar(a[i]+'0');
		if(Entr) putchar('\n');
	}
	void operator = (char *s){
		len=strlen(s);
		for(int i=0,j=len-1;i<len;i++,j--) a[i]=s[j]-48;
		while(len>1&&a[len-1]==0) len--;
	}
	void operator = (int x){
		len=0;if(x==0) len=1,a[0]=0;
		while(x>0) a[len++]=x%10,x/=10;
	}
	void operator = (long long x){
		len=0;if(x==0) len=1,a[0]=0;
		while(x>0) a[len++]=x%10,x/=10;
	}
	friend bool operator < (bign a,bign b){
		if(a.len!=b.len) return a.len<b.len;
		for(int i=a.len-1;i>=0;i--)
			if(a.a[i]!=b.a[i]) return a.a[i]<b.a[i];
		return false;
	}
	friend bool operator > (bign a,bign b){
		return b<a;
	}
	friend bool operator <= (bign a,bign b){
		return !(a>b);
	}
	friend bool operator >= (bign a,bign b){
		return !(a<b);
	}
	friend bool operator == (bign a,bign b){
		return !(a>b&&b<a);
	}
	friend bool operator != (bign a,bign b){
		return a<b||b<a;
	}
	friend bign operator + (bign a,bign b){
		bign c;
		int lenth=max(a.len,b.len)+1;
		for(int i=0;i<lenth;i++) c.a[i]=a.a[i]+b.a[i];
		for(int i=0;i<lenth;i++){
			if(c.a[i]>9) c.a[i]-=10,c.a[i+1]++;
		}
		while(lenth>1&&c.a[lenth-1]==0) lenth--;
		c.len=lenth;
		return c;
	}
	friend bign operator - (bign a,bign b){
		bign c;
		if(a<b) std::swap(a,b);
		int len=a.len;
		for(int i=0;i<len;i++)
			c.a[i]=a.a[i]-b.a[i];
		for(int i=0;i<len;i++)
			if(c.a[i]<0) c.a[i+1]--, c.a[i]+=10;
		while(len>1&&c.a[len-1]==0) len--;
		c.len=len;
		return c;
	}
	friend bign operator * (bign a,bign b){
		bign ans;
		int len=a.len+b.len;
		for(int i=0;i<a.len;i++)
			for(int j=0;j<b.len;j++)
				ans.a[i+j]+=a.a[i]*b.a[j];
		for(int i=0;i<len;i++)
			if(ans.a[i]>9) ans.a[i+1]+=ans.a[i]/10,ans.a[i]%=10;
		while(len>1&&ans.a[len-1]==0) len--;
		ans.len=len;
		return ans;
	}
	friend bign operator * (bign a,int x){
		bign ans;
		int len=a.len+20;
		for(int i=0;i<len;i++) ans.a[i]=a.a[i]*x;
		for(int i=0;i<len;i++)
			if(ans.a[i]>9) ans.a[i+1]+=ans.a[i]/10,ans.a[i]%=10;
		while(ans.a[len-1]==0&&len>1) len--;
		ans.len=len;
		return ans;
	}
	friend bign operator / (bign a,int b){
		bign c;
		int d=0,len=a.len;
		for(int i=len-1;i>=0;i--)
			d=d*10+a.a[i],c.a[i]=d/b,d=d%b;
		while(len>1&&c.a[len-1]==0) len--;
		c.len=len;
		return c;
	}
	friend bign operator / (bign a,bign b){
		bign c,d;
		int len=a.len;
		for(int i=len-1;i>=0;i--){
			d=d*10;
			d.a[0]=a.a[i];
			while(d>=b) c.a[i]++, d=d-b;
		}
		while(len>1&&c.a[len-1]==0) len--;
		c.len=len;
		return c;
	}
	friend int operator % (bign a,int b){
		int d=0,len=a.len;
		for(int i=len-1;i>=0;i--)
			d=d*10+a.a[i],d=d%b;
		return d;
	}
	friend bign operator % (bign a,bign b){
		bign d;
		int len=a.len;
		for(int i=len-1;i>=0;i--){
			d=d*10;
			d.a[0]=a.a[i];
			while(d>=b) d=d-b;
		}
		while(len>1&&d.a[len-1]==0) len--;
		d.len=len;
		return d;
	}
	friend bign gcd(bign a,bign b){
		bign zero;
		zero=0;
		return b==zero?a:gcd(b,a%b);
	}
	friend bign pow_mod(int a,int n,bign m){
		bign ret,X;
		if(n==0){
			ret=1;return ret;
		}
		X=pow_mod(a,n/2,m);
		ret=(X*X)%m;
		if(n%2) ret=(ret*a)%m;
		return ret;
	}
};


猜你喜欢

转载自blog.csdn.net/hi_ker/article/details/80982710