C++大数BigInt

前言

一直在用板子,然后考虑到有些细节还不是很清楚,就整理一下吧。然后没有按板子来写,但是思想基本一致,因为我的板子是每四位合并成一位,也就是将大数看做一个 10000 10000 10000进制数

构造和输出

大数一位位地输入比较慢,因此一般采用字符串输入,然后将字符串转化为大数

注意需要从后向前存,运算时从前向后运算,输出时从后向前输出

const int maxn=1005;

struct BigInt{
    int a[maxn];
    int len;

    BigInt(){ len=1; memset(a,0,sizeof a); }

    BigInt(char *s){
        len=strlen(s);
        int cnt=0;
        for(int i=len-1;i>=0;i--) a[cnt++]=s[i]-'0';
    }

    BigInt(string s){
        len=s.size();
        int cnt=0;
        for(int i=len-1;i>=0;i--) a[cnt++]=s[i]-'0';
    }

    BigInt& operator = (const BigInt &T){   //重载赋值运算符,大数之间进行赋值运算
        len=T.len;
        memset(a,0,sizeof(a));
        for(int i=0;i<len;i++)
            a[i]=T.a[i];
        return *this;
    }
    
    void println(){
        for(int i=len-1;i>=0;i--) printf("%d",a[i]);
        puts("");
    }
    
    void print(){
    	for(int i=len-1;i>=0;i--) printf("%d",a[i]);
	}
};
逻辑比较

>

bool operator > (const BigInt &T) const {
	if(len>T.len) return 1;
	if(len<T.len) return 0;
	int cur=len-1;
	while(a[cur]==T.a[cur] && cur>=0) cur--;
	if(cur>=0 && a[cur]>T.a[cur]) return 1;
	else return 0;
}

<

bool operator < (const BigInt &T) const {
	if(len<T.len) return 1;
	if(len>T.len) return 0;
	int cur=len-1;
	while(a[cur]==T.a[cur] && cur>=0) cur--;
	if(cur>=0 && a[cur]<T.a[cur]) return 1;
	else return 0;
}

==

bool operator == (const BigInt &T) const {
	if(len!=T.len) return 0;
	for(int i=len-1;i>=0;i--)
        if(a[cur]!=T.a[cur]) return 0;
	return 1;
}
四则运算

大数加法

实际上就是对每一位相加并处理进位即可

BigInt operator + (const BigInt &T) const {
	BigInt ret=T;
	int maxlen=len>T.len?len:T.len;  //取长度最长的那个
	for(int i=0;i<maxlen;i++){
		ret.a[i]+=a[i];
		if(ret.a[i]>=10){
			ret.a[i+1]++;
			ret.a[i]-=10;
        }
	}
	ret.len=ret.a[maxlen]>0?maxlen+1:maxlen;
	return ret;
}

大数减法

BigInt operator - (const BigInt &T) const {
	BigInt t1,t2;
	bool flag;
	if(*this>T){  //取得最大数并标记首位是否为负
		t1=*this,t2=T;
		flag=0;
	}else{
		t1=T,t2=*this;
		flag=1;
	}
	int maxlen=t1.len;
	for(int i=0;i<maxlen;i++){
		if(t1.a[i]<t2.a[i]){  //需要向前借位
			int j=i+1;
			while(t1.a[i]==0) j++;
			t1.a[j--]--;
			while(j>i) t1.a[j--]=9;
			t1.a[i]+=10-t2.a[i];
		}else t1.a[i]-=t2.a[i];
	}
	while(t1.a[maxlen-1]==0 && t1.len>1){   //看看从最高位开始是否被借位变为0
		t1.len--;
		maxlen--;
	}
	if(flag) t1.a[maxlen-1]=-t1.a[maxlen-1]; //处理首位的正负
	return t1;
}

大数乘法

BigInt operator * (const BigInt &T) const {
	BigInt ret;
	int i,j,temp1,temp2,up;
	for(i=0;i<len;i++){
		up=0;
		for(j=0;j<T.len;j++){
			temp1=a[i]*T.a[j]+ret.a[i+j]+up;
			if(temp1>=10){
				temp2=temp1-temp1/10*10;
				up=temp1/10;
				ret.a[i+j]=temp2;
			}else{
				up=0;
				ret.a[i+j]=temp1;
			}
		}
		if(up) ret.a[i+j]=up;  //向最高位的进位是否存在
	}
	ret.len=len+T.len;
	while(ret.a[ret.len-1]==0 && ret.len>1) ret.len--;  //处理前导0
	return ret;
}

大数除法

BigInt operator / (const int &b) const {
	BigInt ret;
	int down=0;
	for(int i=len-1;i>=0;i--){
		ret.a[i]=(a[i]+down*10)/b;
		down=a[i]+down*10-ret.a[i]*b;
	}
	ret.len=len;
	while(ret.a[ret.len-1]==0 && ret.len>1) ret.len--;
	return ret;
}
其他操作

大数取模

43 43%3 43为例:
在这里插入图片描述

然后我们可以发现实际上需要的是对每一位依次取模,并加上来自高位的余数乘以十

int operator % (const int &b) const {
	int ret=0;
	for(int i=len-1;i>=0;i--)
		ret=(ret*10+a[i])%b;
	return ret;
}

大数求幂

BigInt pow(int n){   //传入的n非负
	BigInt x=*this,ret("1");
	while(n) {
		if(n&1) ret=ret*x;
		x=x*x;
		n>>=1;
	}
	return ret;
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值