算法笔记-数学问题-高精-大整数

何时使用高精度?

int 最大数的数位为10位,即大约为2*(32-1)=2,147,483,648,取值范围-231~(231-1),大约为109
unsigned int 最大数的数位为10位,即大约为2*32=4,294,967,296,取值范围0~(232-1),大约为109
long long 最大数的数位19,即大约为2^(64-1)=9,223,372,036,854,775,808,取值范围-263~(263-1),大约为1018
unsigned long long 最大数的数位20,即大约为2^64=18,446,744,073,709,551,616,取值范围0~(264-1),大约为1019
超过10^19数量级一般选用Java大数解决

高精度操作

高精度结构体

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

字符数组转换为高精度

bign change(char str[]) {
	bign a;
	a.len=strlen(str);
	for(int i=0; i<a.len; i++) {
		a.d[i]=str[a.len-1-i];
	}
	return a;
}

高精度乘低精度

bign multi(bign a, int b) {
	bign c;
	int r = 0;
	for(int i=0; i<a.len; i++) {
		int t = a.d[i]*b+r; //当前数字乘积
		c.d[c.len++] = t%10; //取当前乘积的个位
		r = t/10; //更新余数
	}
	while(r!=0) { //处理未处理的高位余数
		c.d[c.len++]=r%10;
		r /= 10;
	}
	return c;
}

高精度除以低精度

bign divid(bign a, int b, int &r) {
	bign c;
	c.len=a.len; //商和被除数位数一一对应
	for(int i=0; i<a.len; i++) {
		int t = r*10+a.d[i];
		if(t<b) { //不够除,当前位为0
			c.d[i]=0;
		} else { //够除,
			c.d[i]=t/b;
			r = t%b;
		}
	}
	while(c.len-1>=1&&c.d[c.len-1]==0) c.len--; //处理高位0
	return c;
}

高精度加法

bign add(bign a, bign b) {
	bign c;
	int r = 0;
	for(int i=0; i<a.len; i++) {
		int t = a.d[i]+b.d[i]+r;
		c.d[c.len++]=t%10; //取个位数
		r = t/10; //更新余数
	}
	if(r!=0)c.d[c.len++]=r;//处理最后的进位
	return c;
}

高精度减法

bign sub(bign a, bign b) {
	bign c;
	int r=0;
	for(int i=0; i<a.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--; //处理高位的0
	return c;
}
posted @ 2020-07-10 10:48  JamieHou  阅读(188)  评论(0编辑  收藏  举报