高精度算法

先总结

用脑子计算是"竖式"(小学知识,不会算了),用电脑计算是利用了竖式计算的原理

存数字

string类型
一个循环存入一个数组

高精度加法

原理

从低位开始加,大于10,则下一位加1

实现

从低位开始

将数组翻转(reverse)

加法

不说了,不会自己回幼儿园重修

进位

一个 i f if if

代码

注意初始化

string add(string a,string b){
	int l1=a.length(),l2=b.length(),x[10086]={ },y[10086]={ },ans[10086]={ };
	string c;
	for(int i=0;i<l1;i++){
		x[i]=a[i]-'0';
	}
	for(int i=0;i<l2;i++){
		y[i]=b[i]-'0';
	}
	reverse(x,x+l1);
	reverse(y,y+l2);
	for(int i=0;i<max(l1,l2);i++){
		int t=ans[i]+x[i]+y[i];
		ans[i]=t%10;
		ans[i+1]=t/10;
	}
	bool flag=0;
	if(ans[max(l1,l2)]!=0) flag=1;
	reverse(ans,ans+max(l1,l2)+flag);
	for(int i=0;i<+max(l1,l2)+flag;++i){
		c+=ans[i]+'0';
	}
	return c;
}

高精度乘法

原理

从低位到高位,数a第k位,数b第l位,乘起来的个位的位置在(l+k)位

实现

从低位到高位

reverse

乘法

回小学重修

进位

i f if if

代码

注意高位的特判

string mul(string a,string b){
	string c;
	if(a=="0"||b=="0") {
		c+="0";
		return c;
	}
	int l1=a.length(),l2=b.length(),x[5005]={ },y[5005]={ },ans[10086]={ };
	for(int i=0;i<l1;i++){
		x[i]=a[i]-'0';
	}
	for(int i=0;i<l2;i++){
		y[i]=b[i]-'0';
	}
	reverse(x,x+l1);
	reverse(y,y+l2);
	for(int i=0;i<l1;i++){
		for(int j=0;j<l2;j++){
			int p=i+j;
			int t=x[i]*y[j]+ans[p];
			if(t>=10){
				ans[p+1]+=t/10;
			}
			ans[p]=t%10;
		}
	}
	int flag=0;
	if(ans[l1+l2-1]!=0) flag=1;
	reverse(ans,ans+l1+l2-1+flag);
	for(int i=0;i<l1+l2-1+flag;++i){
//		cout << ans[i];
		c+=ans[i]+'0';
	}
	return c;
}

高精度减法

不讲原理了

实现

借位

一个if

前导零

打个while

代码

string sub(string a,string b){
	if(a==b) {
		return "0";
	}
	int l1=a.length(),l2=b.length(),x[5005],y[5005],ans[5005];
	for(int i=0;i<l1;i++){
		x[i]=a[i]-'0';
	}
	for(int i=0;i<l2;i++){
		y[i]=b[i]-'0';
	}
	reverse(x,x+l1);
	reverse(y,y+l2);
	for(int i=0;i<max(l1,l2);i++){
		if(x[i]<y[i]){
			x[i+1]--;
			x[i]+=10;
		}
		ans[i]=x[i]-y[i];
	}
	reverse(ans,ans+max(l1,l2));
	string c;
	bool flag=1;
	for(int i=0;i<max(l1,l2);++i){
		if(ans[i]==0&&flag) continue;
		flag=0;
		c+=ans[i]+'0';
	}
//	reverse(c.begin(),c.end());
	return c;
}

高精度除法

前言

小编没有写高精/低精
直接讲高精除以高精

实现

判断当前处理的哪几位

1.

处理的位数=除数的位数

2.

处理的位数=除数的位数+1

自己打函数

计算商

用高精度减法暴力

代码

注意前导零
s t r i n g   s u b ( s t r i n g   a , s t r i n g   b ) string\ sub(string\ a,string\ b) string sub(string a,string b) :
高精度减法

string div(string a,string b){
	int ans[5005];
	int l=0;
	string c; 
	for(int i=0;i<a.length();++i){
//		cout << i << " *";
		c=a.substr(l,i-l+1);
//		cout << c << " ";
		int t=0;
		while(cmp(c,b)){
			++t;
			c=sub(c,b);
		} 
//		cout << c << " ";
//		cout << c << "&";
//		if(c!=a.substr(l,i-l+1)){
//			for(int j=i;j>=l;--j){
//				if(i-j+1<=c.length()){
//					a[j]=*(c.end()-(i-j+1));
//				}else{
//					a[j]='0';
//				}
//			}
//			while(a[l]=='0') ++l;
//			ans[i]=t;
//		}
//		cout << a << " ";
		a.erase(l,i-l+1);
//		cout << a << " ";
		a.insert(l,c);
		for(int j=1;j<=(i-l+1)-c.length();++j){
			a.insert(0,"0");
		}
		while(a[l]=='0') ++l;
		ans[i]=t;
//		cout << a << " " << l << " " << t << endl;
	}
	c="";
	for(int i=0;i<a.length();++i){
		c+=ans[i]+'0';
	}
	return c;
}

总结

竖式到代码的转换,类似于模拟,嘿嘿嘿

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值