入门数学(三)大整数运算

一, 大数的储存

A+B的题目如果A和B在long long 范围内,那就太简单了,一般怎么会有这么简单的题呢?如果出A+B那肯定有个坑等着你里,

A和B如果是 1000位的数。

那么我们可以定义一个Int 型的整型数组,d[1000]那么这个数组中的每一位就代表了存放的整数的每一位,我们动手试一试

咦发现,这样存可以但是,算+ - 乘除的时候怎么算啊,对了,那我们就倒着存试试?动动试试,在纸上画画,好像+-乘除能算了。

在需要的时候将数组反转一下就可以了。

为了方便我们将大数存到一个结构体内,方便读取长度

struct bign{
	int d[1000];
	int len;
	bign(){	//初始化结构体 
		memset(d, 0, sizeof(d));
		len = 0;
	}
};

这样我们再读大数的时候就可以先用字符串去读,然后再把字符串另存到bign的结构体中,用string读长的数字。

bign change(string s){
	bign a;
	a.len = s.length();
	for(int i = 0; i < a.len; i++){
		a.d[i] = s[a.len - i - 1] - '0';
	}
	return a;
} 

如果要比较两个bign的大小简单,2种情况,长度不等,长度相1)同时,

int compare(bign a, bign b){
	if(a.len > b.len) return 1;		// a大 
	else if( a.len < b.len)	return -1;		//a小 
	else{
		for(int i = a.len - 1; i >= 0; i--){
			if(a.d[i] > b.d[i]) return 1;
			else if(a.d[i] < b.d[i]) return -1;
		} 
		return 0;
	} 
}

1)大数相加

bign add(bign a, bign b){
	bign c;
	int carry = 0;	//carry是进位
	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;
}

2)大数相减

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];
	}
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0){
		c.len--;
	}
	return c;
}

3)大数相乘(高精度乘低精度)

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;
} 

4)大数相除(高精度除低精度)

bign divide(bign a, int b, int &r){ 	//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;
		else{
			c.d[i] = r / b;
			r = r % b;
		}
	}
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0){
		c.len--;
	} 
	return c;
}

猜你喜欢

转载自blog.csdn.net/Harington/article/details/87724720