大整数运算(算法笔记学习总结)

①什么是大整数:高精度整数,用基本数据类型无法存储其精度的整数,例如有1000个位数的整数。
②存储:用数组,整数的高位存储在数组的高位,整数的低位存储在数组的低位。输出的时候逆序输出。
(1)大整数结构体:

struct bign{
	int d[1000];
	int len;//方便获取大整数的长度
	//构造函数(函数名与结构体相同,无返回值)初始化结构体 
	bign(){
		memset(d,0,sizeof(d));
		len = 0; 
	} 
}; 

(2)输入大整数,运用字符串,再存至结构体:

bign change(char str[]){
	bign a;
	a.len = strlen(str);//大整数长度 
	for(int i=0;i<a.len;i++){
		a.d[i] = str[a.len-i-1] - '0';//逆序赋值 
	}
	return a; 
}

③应用:
(1)比较两数大小
规则:先比长度,不等出结果;相等从高位到低位比较,直到不等得结果,都不满足则两数相等。

int compare(bign a,bign b){
	//a比b大 ,返回1 
	if(a.len>b.len){
		return 1;
	} 
	//b比a大,返回-1 
	else if(a.len<b.len){
		return -1;
	} 
	//否则从高位到低位判断
	else{
		for(int i=a.len-1;i>=0;i--){
			if(a.d[i]>b,d[i]) return 1;//a大返回1 
			else if(a.d[i]<b.d[i]) return -1;//b大返回-1 
		}
		//否则相等,返回0 
		return 0; 
	} 
} 

(2)四则运算(模拟加减乘除的过程)
高精度加法:

bign add(bign a,bign b){
	bign c;
	int carry = 0;//进位
	for(int i=0;i<a.len||i<b.len;i++){//长的为界限
	     int temp = a.d[i] + b.d[i] + carry;//相应位与进位相加
		 c.d[c.len++] = temp%10;//个位结果
		 carry = temp/10;//新的进位 
	}
	//判读最后的进位 
	if(carry!=0){
		c.d[c.len++] = carry;
	} 
	 return c;
} 

练习例子:
https://editor.youkuaiyun.com/md/?articleId=108066267
注意:该例子的两数都是非负整数。

高精度减法:

注意比较两数的大小;注意删掉高位的0。

bign sub(bign a,bign b){
	bign c;
	for(int i =0;i<a.len||i<b.len;i++){
		if(a.d[i]<b.d[i]){
			a.d[i+1]--;//高位减一
			a.d[i] += 10;//低位加十 
		}
		c.d[c.len++] = a.d[i] - b.d[i];//各位减的结果 
	}
	//删除高位的0
	while(c.len - 1>=1 && c.d[c.len - 1] ==0){
		c.len --;
	} 
	return c;
} 

高精度与低精度(可以用基本数据类型存储)的乘法:
与平常的做法不太一样。
具体步骤位:
取bign的某位与int类型整体相乘,再与进位相加,得到的结果的个位作为该位结果,高位部分作为新的进位。

bign multi(bign a,int b){
	bign c;
	int carry = 0;
	for(int i=0;i<a.len;i++){
		int temp = a.d[i]*b +carry;
		c.d[c.len++] = temp%10;//个位作为该位结果
		carry = temp / 10;//高位部分作为新的进位 
		}
		//乘法可能有多个进位,区别于加法 
		while(carry != 0){
			c.d[c.len++] = carry %10;
			carry /= 10;
		} 
		return c; 
} 

高精度与低精度的除法:
具体步骤:
上一步的余数乘以10加上该位的数,得到临时的被除数,与除数比较,不够除,该位为0,够除,商就是对应的商,余数就是对应的余数。
注意高位为0需要删除
这里传递了三个参数,余数用的是引用。注意区别前面的三种运算。

//r是余数 
bign divide(bign a,int b,int &r){
	bign c;
	//被除数每位与商的每位一一对应,故开始长度相等。 
	c.len = a.len;
	//从高位开始相除 
	for(int i = a.len - 1;i>=0;i--){
		//与上一位的余数组合 
		r = r*10+a.d[i];
		if(r<b)c.d[i] = 0;//不够除,则为0
		else{//够除 
			c.d[i] = r/b;//得到的商
			r = r%b;//获得新的余数 
		} 
	} 
	//去掉高位0,同时保留至少一位。 
	while(c.len - 1 >= 1 && c.d[c.len-1]==0){
		c.len --;
	} 
	return c; 
} 

总结:四种情况有很多相似之处,注意区分,还是需要记住每种写法,才利于使用,总的来说还是很简单的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值