C++高精度模板

目录

一.高精度介绍

二.模板

感谢各位大佬的阅读!


一.高精度介绍

通常,我们只会用string去做关于字符串的题,但是高精度还有另外一个用法,那就是高精度。众所周知,int的范围是-2147483648到2147483647,long long的范围是-2^63到2^63-1。但是有一些题它的范围大于int和long long的范围,这是就需要高精度来帮忙。这是它的定义:

二.模板

高精加:

#include<bits/stdc++.h>
using namespace std;
string a,b;
int s1[255],s2[255],s3[255];
int main(){
	cin>>a>>b;
	int len1=a.size();
	int len2=b.size();
	for(int i=0;i<len1;i++){
		s1[i]=a[len1-i-1]-'0';
	}
	for(int i=0;i<len2;i++){
		s2[i]=b[len2-i-1]-'0';
	}
	int maxn=max(len1,len2);
	int x=0;
	for(int i=0;i<=maxn;i++){
		s3[i]=s1[i]+s2[i]+x;
		x=s3[i]/10;
		s3[i]%=10;
	}
	if(s3[maxn]>0) maxn++;
	for(int i=maxn-1;i>=0;i--) cout<<s3[i];
	return 0;
}

高精减:

#include<bits/stdc++.h>
using namespace std;
string a,b;
int s1[114514],s2[114514],s3[114514];
int main(){
	cin>>a>>b;
	int len1=a.size();
	int len2=b.size();
	int maxn=max(len1,len2);
	if(len1<len2){
		cout<<"-";
        swap(a,b);
        swap(len1,len2);
    }
	if(len1==len2){
		for(int i=0;i<maxn;i++){
			if(a[i]<b[i]){
				swap(a,b);
                swap(len1,len2);
                cout<<"-";
				break;
			}
			
		}
	}
	for(int i=0;i<len1;i++){
		s1[i]=a[len1-i-1]-'0';
	}
	for(int i=0;i<len2;i++){
		s2[i]=b[len2-i-1]-'0';
	}
	for(int i=0;i<=maxn;i++){
		if(s1[i]-s2[i]<0){
			s1[i]+=10;
			s1[i+1]-=1;
		}
		s3[i]=s1[i]-s2[i];
	}
	if(s3[maxn]>0) maxn++;
	while(s3[maxn]==0 && maxn>0) maxn--;
	for(int i=maxn;i>=0;i--) cout<<s3[i];
	return 0;
}

高精乘:

#include<bits/stdc++.h>
using namespace std;
string a,b;
int s1[255],s2[255],s3[1145141];
int main(){
	cin>>a>>b;
	int len1=a.size();
	int len2=b.size();
	int maxn=len1+len2;
	for(int i=0;i<len1;i++){
		s1[i]=a[len1-i-1]-'0';
	}
	for(int i=0;i<len2;i++){
		s2[i]=b[len2-i-1]-'0';
	}
	for(int i=0;i<=len1;i++){
		int x=0;
		for(int j=0;j<len2;j++){
			s3[i+j]+=s1[i]*s2[j]+x;
			x=s3[i+j]/10;
			s3[i+j]%=10;
		}
		s3[i+len2]+=x;
	}
	if(s3[maxn]>0) maxn++;
	while(s3[maxn]==0 && maxn>0) maxn--;
	for(int i=maxn;i>=0;i--) cout<<s3[i];
	return 0;
}

高精除低精:

#include<bits/stdc++.h>
using namespace std;
int a[114514],sum;
int main(){
	string s;cin>>s;
	int len=s.size();
	for(int i=0;i<len;i++){
		sum=sum*10+(s[i]-'0');
		a[i]=sum/13;
		sum%=13;
	}
	int pos=0;
	while(a[pos]==0 && pos<len-1){
		pos++;
	}
	for(int i=pos;i<len;i++){
		cout<<a[i];
	}
	cout<<endl<<sum;
	return 0;
}

高精除高精:

#include<bits/stdc++.h>
#include<cmath>
using namespace std;
int dPZ(int x[],int xLen){
    int i=xLen;
    while(x[i-1]==0&&i>1){
        i--;
    }
    return i;
}
void printArr(int x[],int xLen){
    for(int i=xLen-1;i>=0;i--){
        cout<<x[i];
    }
    cout<<endl;
}
bool cp(int x[],int y[],int xLen,int yLen){
    if(xLen<yLen){
        return false;
    }
    if(xLen==yLen){
        for(int i=xLen-1;i>=0;i--){
            if(x[i]>y[i]){
                return true;
            }
            if(x[i]<y[i]){
                return false;
            }
        }
        return true;
    }
    return true;
}
int sub(int x[],int y[],int z[],int xLen,int yLen){
    int zLoc=xLen-yLen; 
    for(int i=1;i<=yLen;i++){
        if(x[xLen-i]>y[yLen-i])
            break;
        if(x[xLen-i]<y[yLen-i]){
            zLoc--;
            break;
        }
    }
    if(zLoc<0) 
        return xLen;
    for(int i=zLoc,j=0;i<xLen&&j<yLen;i++,j++){
        while(x[i]<y[j]){
            x[i+1]--;
            x[i]+=10;
        }
        x[i]-=y[j];
    }
    z[zLoc]++;
    while(x[xLen-1]==0)
        xLen--;
    if(xLen<=0)
        xLen=1;
    return xLen;
}
int main(){
    char as[301],bs[301];
    int a[301]={0},b[301]={0},c[301]={0};
    int aLen=0,bLen=0,cLen=1,maxLen=0;
    int i;
    cin>>as>>bs;
    aLen=strlen(as);
    bLen=strlen(bs);
    for(i=0;i<aLen;i++){
        a[i]=as[aLen-1-i]-'0';
    }
    for(i=0;i<bLen;i++){
        b[i]=bs[bLen-1-i]-'0';
    }
    aLen=dPZ(a,aLen);
    bLen=dPZ(b,bLen);
    cLen=aLen-bLen+1;
    while(cp(a,b,aLen,bLen)){
        aLen=sub(a, b, c, aLen, bLen);
    }
    if(cLen<1){
        cLen=1;
    }
    cLen=dPZ(c,cLen);
    printArr(c,cLen);
    printArr(a,aLen);
    return 0;
}

高精阶乘:

#include<bits/stdc++.h>
using namespace std;
int a[1145141];
int main() {
	int sum,pos=1,n,num;
	cin>>n;
	a[0]=1;
	for(int i=2;i<=n;i++){
		num=0;
		for(int j=0;j<pos;j++){
			sum=a[j]*i+num;
			a[j]=sum%10;
			num=sum/10;
		}
		while(num){
			a[pos]=num%10;
			num/=10;
			pos++;
		}
	}
	for(int i=pos-1;i>=0;i--){
		cout<<a[i];
	}
	return 0;
}

高精封装(将以上几种用结构体封装起来):

#include<bits/stdc++.h>
using namespace std;
struct node{
	int a[10005];
	int len;
	node(){
		memset(a,0,sizeof(a));
		len=0;
	}
	int &operator [](int x){
		return a[x];
	}
	void input(){
		string s;cin>>s;
		len=s.size();
		reverse(s.begin(),s.end());
		for(int i=0;i<len;i++){
			a[i]=s[i]-'0';
		}
	}
	void print(){
		for(int i=len-1;i>=0;i--){
			cout<<a[i];
		}
		cout<<endl;
	}
	void dao(int l){
		len=l;
		for(int i=0;i<len;i++){
			a[i+1]+=a[i]/10,a[i]%=10;
		}
		while(a[len-1]==0&&len>0) len--;
	}
}x,y,p;
node operator +(node x,node y){
	node ans=node();
	int mlen=max(x.len,y.len);
	for(int i=0;i<mlen;i++){
		ans[i]=x[i]+y[i];
	}
	ans.dao(mlen+1);
	return ans;
}
bool cmp(node s,node st){
	if(s.len!=st.len) return s.len<st.len;
	for(int i=s.len-1;i>=0;i--){
		if(s[i]!=st[i]) return s[i]<st[i];
	}
	return false;
}
node operator -(node x,node y){
	node ans=node();
	int mlen=max(x.len,y.len);
	int flag=cmp(x,y)?0:1;
	for(int i=0;i<mlen;i++){
		if(flag==1) ans[i]=x[i]-y[i];
		else ans[i]=y[i]-x[i];
	}
	for(int i=0;i<mlen;i++){
		while(ans[i]<0) ans[i+1]--,ans[i]+=10;
	}
	ans.dao(mlen);
	if(ans.len==0) ans.len=1,ans[0]=0;
	if(cmp(x,y)) cout<<"-";
	return ans;
}
node operator *(node x,node y){
	node ans=node();
	int aans=-1,sum;
	for(int i=0;i<y.len;i++){
		aans++;
		ans.len=aans;
		for(int j=0;j<x.len;j++){
			ans[ans.len]+=x[j]*y[i];
			if(ans[ans.len]>=10){
				ans[ans.len+1]+=ans[ans.len]/10;
				ans[ans.len]%=10;
			}
			ans.len++;
		}
	}
	while(ans[ans.len]!=0) ans.len++; 
	ans.dao(ans.len);
	if(ans.len==0) ans.len=1,ans[0]=0;
	return ans;
}
node nde(int x){
	node ans=node(); 
	do{
		ans[ans.len]=x%10;
		ans.len++;
	}while((x/=10)!=0);
	return ans;
}
node operator / (node x,node y){
	node u,c;
	for(int i=x.len-1;i>=0;i--){
		u=u*nde(10)+nde(x[i]);
		while(!cmp(u,y)){
			u=u-y;
			c[i]++;
		}
	}
	c.dao(x.len+1);
	if(c.len==0) c.len=1,c[0]=0;
	return c;
}
node operator % (node x,node y){
	node u,c;
	for(int i=x.len-1;i>=0;i--){
		u=u*nde(10)+nde(x[i]);
		while(!cmp(u,y)){
			u=u-y;
			c[i]++;
		}
	}
	if(u.len==0) u.len=1,u[0]=0;
	return u;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
    x.input();
    y.input();
	p=x+y;
	p.print();
	p=x-y;
	p.print();
	p=x*y;
	p.print();
	p=x/y;
	p.print();
	p=x%y;
	p.print();
	return 0;
}

感谢各位大佬的阅读!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值