【机试练习】【C++】高精度/大整数运算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Xiblade/article/details/82778126
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

const int MAXLEN = 10000; // 最大支持数值长度 

struct Bign{
	int d[MAXLEN];
	int len;
	Bign(){
		memset(d, 0, sizeof(d));
		len = 0;
	}
};

//将字符数组存储的整数转换为Bign 
Bign toBign(char str[]){ 
	Bign a;
	a.len = strlen(str);
	for(int i = 0; i < a.len; i++){
		a.d[i]/*i 前面的*/ = str[a.len - i - 1] /*总长度 - i - 1 是后面的*/- '0';
	}
	return a; 
}

// 大的存储在低位,则需要先输出低位再输出高位 
void printBign(Bign a){
	for(int i = a.len - 1; i >= 0; i--){
		printf("%d", a.d[i]);
	}
}

// 比较大小
int compareBign(Bign a, Bign b){
	// 先比较哪个长 
	if(a.len > b.len) return 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;
			else if(a.d[i] < b.d[i]) return -1;
		}
	}
	return 0;
} 

// 高精度加法 
Bign addBign(Bign a, Bign b){
	Bign rt;
	int carry = 0; // 进位缓存
	for(int i = 0; i < a.len || i < b.len; i++){
		int tmp = a.d[i] + b.d[i];
		rt.d[rt.len ++] = tmp % 10 + carry;
		carry = tmp / 10;
	} 
	//处理一下进位
	if(carry != 0){
		rt.d[rt.len ++] = carry;
	} 
	return rt;
}

// 高精度减法
Bign subBign(Bign a, Bign b){ // 计算 |a - b|
	Bign rt;
	if(compareBign(a, b) == -1){ // 如果小了则置换 
		Bign tmp = a;
		a = b;
		b = tmp;
	}
	for(int i = 0; i < a.len || i < b.len; i++){
		// 先判断够不够减
		if(a.d[i] < b.d[i]){ // 不够减就让高位借10 
			a.d[i + 1] --;
			a.d[i] += 10;
		} 
		rt.d[rt.len++] = a.d[i] - b.d[i];
	}
	while(rt.len - 1 > 1 && rt.d[rt.len - 1] == 0){ // 最高位为零 则长度减少 
		rt.len --;
	}
	return rt;
} 

// 高精度与低精度乘法
Bign multiBignAndInt(Bign a, int b){
	Bign rt;
	int carry = 0;
	for(int i = 0; i < a.len; i++){
		// 自低位到高位,轮流在高精度整数中取值
		// 与低精度相乘再加进位
		int temp = a.d[i] * b + carry; 
		// 剔除temp中的进位 
		rt.d[rt.len ++] = temp % 10;
		carry = temp / 10;  // 这个进位不一定是个位数 
	}
	while(carry != 0){
		rt.d[rt.len ++] = carry % 10;
		carry /= 10; 
	}
	return rt;
} 

Bign divideBignAndInt(Bign a, int b, int &r){
	Bign rt;
	rt.len = a.len; // 先将商的每一位与被除数对应 
	r = 0; // 向外传递的余数初始化 
	for(int i = a.len - 1; i >= 0; i--){ // 从高位开始除 
		r = r * 10 + a.d[i];// 上一位的余数与这一位的数值结合形成新的数
		if(r < b) // 不够除
			rt.d[i] = 0;
		else{
			rt.d[i] = r / b;
			r = r % b;
		}
	}
	// 去掉0
	while(rt.len - 1 >= 1 && rt.d[rt.len - 1] == 0){
		rt.len --;
	} 
	
	return rt;
}

int main(){
	Bign a = toBign("123443");
	Bign b = toBign("123456123456");
	int r = 0;
	printBign(divideBignAndInt(b, 54, r));
	printf("\n%d", r);
	return 0; 
}
 

猜你喜欢

转载自blog.csdn.net/Xiblade/article/details/82778126