高精度算法(c++)

目录

1.高精度算法介绍:

2.高精度算法应用:

高精度加法

高精度减法

           高精度乘法

           高精度除法

高精度算法真题:

1.高精度算法介绍:

在C++中,高精度和低精度通常指的是处理数字时所用的数据结构的精度高低。例如,如果你使用内置的整型(如intlonglong long)来处理较大的数字,它们可能会溢出,这时你可能会使用数组或者std::vector来模拟大整数,这样的结构就可以看作是高精度数据类型。而对应地,低精度可以理解为使用较小的数据类型,如charshort或内置的整数类型。

       C++标准规定:

       int占一个机器字长,在32位系统中int占32位,即4个字节,所以int的范围是[-,],为数量级。long long的范围则是[,],为数量级。如果超过该数量级,就需要用到高精度算法。

2.高精度算法应用:

      高精度加法
     1.输入两个整数a,b,输出它们的和(a,b<=)

       直接使用int/long long进行设变量计算。

      2.输入两个整数a,b,输入它们的和(a,b<=)

       分析:int:~,数量级为,long long:~,数量级为,解决方案:用数组模拟高精度。

        算法核心:c[i]=a[i]+b[i],c[i+1]=c[i]/10,c[i]=c[i]%10;

#include<bits/stdc++.h>
using namespace std;
char s1[505],s2[505];
int a[505],b[505],c[505];
int main(){
	int la,lb,lc;
	cin>>s1>>s2;//用数组模拟加法,数组输入
	la=strlen(s1);
	lb=strlen(s2);
	for(int i=0;i<la;i++){//倒置过来
		a[la-i]=s1[i]-'0';
	}
	for(int i=0;i<lb;i++){
		b[lb-i]=s2[i]-'0';
	}
	lc=max(la,lb)+1;
	for(int i=1;i<=lc;i++){//使用数组进位模拟加法
		c[i]+=a[i]+b[i];
		c[i+1]+=c[i]/10;
		c[i]%=10;
	}
	if(c[lc]==0&&lc>1){//去掉前导0
		lc--;
	}
	for(int i=lc;i>0;i--){//倒序输出
		cout<<c[i];
	}
	return 0;
} 

高精度减法

要点:1.如果a<b,则需要交换a与b,最后计算完以后添加一个负号即可。2.如果a[i]<b[i],需要高位借一当十使用。

#include<bits/stdc++.h>
#include<cstring>
#include<algorithm>
#include<string>
#define maxn 10100
using namespace std;
int a[maxn],b[maxn],c[maxn],flag;
string m,n,s;
bool compare(string s1,string s2){
	if(s1.length()!=s2.length()){
		return s1.length()>s2.length();
	}
	for(int i=s1.length()-1;i>=0;i--){
		if(s1[i]!=s2[i]){
			return s1[i]>s2[i];
		}
	}
	return true;
}
int main(){
	cin>>m>>n;
	if(!compare(m,n)){
		flag=1;
		s=m;
		m=n;
		n=s;
	}
	int len=max(m.length(),n.length());
	for(int i=m.length()-1,j=1;i>=0;i--,j++){
		a[j]=m[i]-'0';
	}
	for(int i=n.length()-1,j=1;i>=0;i--,j++){
		b[j]=n[i]-'0';
	}
	for(int i=1;i<=len;i++){
		if(a[i]<b[i]){
			a[i+1]--;
			a[i]+=10;
		}
		c[i]=a[i]-b[i];
	}
	while(c[len]==0&&len>1){
		len--;
	}
	if(flag==1){
		cout<<"-";
	}
	for(int i=len;i>0;i--){
		cout<<c[i];
	}
	return 0;
}

     高精度乘法:
      通过图示分析,我们发现规律,a[1]*b[1]对应c[1]位置,a[2]*b[1]对应c[2]位置,a[3]*b[1]对应c[3]位置,a[4]*b[1]对应c[4]位置,a[1]*b[2]对应c[2],a[2]*b[2]对应c[3]位置,a[3]*b[2]对应c[4]位置,a[4]*b[2]对应c[5]位置。 

#include<bits/stdc++.h>
using namespace std;
char s1[2005],s2[2005];
int a[2005],b[2005],c[4005];
int main(){
	int la,lb,lc;
	cin>>s1>>s2;
	la=strlen(s1);
	lb=strlen(s2);
	for(int i=0;i<la;i++){
		a[la-i]=s1[i]-'0';
	} 
	for(int i=0;i<lb;i++){
		b[lb-i]=s2[i]-'0';
	} 
	lc=la+lb;
	for(int i=1;i<=la;i++){
		for(int j=1;j<=lb;j++){
			c[i+j-1]+=a[i]*b[j];
			c[i+j]+=c[i+j-1]/10;
			c[i+j-1]=c[i+j-1]%=10;
		}
	}
	while(c[lc]==0&&lc>1){
		lc--;
	}
	for(int i=lc;i>0;i--){
		cout<<c[i];
	}
	return 0;
}

高精度除法

高精度除以低精度 

也就是大数除以小数,使用逐位试商法(也就是不断求商和求余数的过程)

#include<bits/stdc++.h>
using namespace std;
char s1[5005];//存储大数 
long long b;//存储小数
long long a[5005],c[5005],la,lc,x; 
int main(){
	cin>>s1>>b;
	la=strlen(s1);//被除数的长度 
	for(int i=1;i<=la;i++){
		a[i]=s1[i-1]-'0';
	}
	for(int i=1;i<=la;i++){
		c[i]=(x*10+a[i])/b;//求商 
		x=(x*10+a[i])%b;//求余数 
	}
	lc=1;
	while(c[lc]==0&&lc<la){
		lc++;
	} 
	for(int i=lc;i<=la;i++){
		cout<<c[i];
	} 
	return 0;
}
高精度除以高精度

方法:减法模拟除法

#include<bits/stdc++.h>
using namespace std;
char s1[305],s2[305];
int a[305],b[305],c[305],tmp[305];//a为被除数,b为除数,c为商
void init(int *x){
	char s[305];
	cin>>s;
	x[0]=strlen(s);
	for(int i=0;i<x[0];i++){
		x[x[0]-i]=s[i]-'0';//将字符串转化为数字,并且倒叙存储 
	}
} 
void print(int a[]){
	if(a[0]==0){
		cout<<0;
		return;
	}
	for(int i=a[0];i>0;i--){
		cout<<a[i];
	}
	return;
}
int compare(int a[],int b[]){//返回1表示a>b,返回0表示a=b,返回-1表示a<b 
 
	if(a[0]>b[0]){
		return 1;
	}
	if(a[0]<b[0]){
		return -1;
	}
	for(int i=a[0];i>0;i--){
		if(a[i]>b[i]){
			return 1;
		}
		if(a[i]<b[i]){
			return -1;
		}
	}
	return 0;
}
void minu(int a[],int b[]){
	for(int i=1;i<=a[0];i++){
		if(a[i]<b[i]){
			a[i+1]--;
			a[i]+=10;
		}
		a[i]=a[i]-b[i];
	}
	while(a[a[0]]==0&&a[0]>0){
		a[0]--;
	}//删除a的前导0,修正a的位数 
}
void numcpy(int p[],int q[],int n){//将除数移动相应的位数 
	for(int i=1;i<=p[0];i++){
		q[i+n-1]=p[i];
	}
	q[0]=p[0]+n-1;//移动后数组的位数 
}
int main(){
	init(a);//输入a 
	init(b);//输入b
	c[0]=a[0]-b[0]+1;
	for(int i=c[0];i>=1;i--){
		memset(tmp,0,sizeof(tmp));
		numcpy(b,tmp,i);//除数移动相应的位数 
		while(compare(a,tmp)>=0){//当被除数大于除数时执行循环 
			c[i]++;
			minu(a,tmp);
		}
	} 
	while(c[c[0]]==0&&c[0]>1){
		c[0]--;
	}
	print(c);//商 
	cout<<endl;
	print(a);//余数 
	return 0;
} 

高精度算法真题:

高精度加法

题目描述

求a+b, 其中,a,b为两个不超过200位的非负整数。

输入样例:

有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。

输出:

一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

输入样例:

22222222222222222222
33333333333333333333

输出样例:

55555555555555555555

【源代码】: 

#include <bits/stdc++.h>
using namespace std;
const int N=205;
int a[N],b[N],c[N];
int main(){
	string sa,sb;//看成字符串,防止数字超范围
	cin>>sa>>sb;
	int la=(int)sa.size();//sa字符串的长度 
	int lb=(int)sb.size();//sb字符串的长度 
	for(int i=0;i<la;i++) a[i]=sa[la-1-i]-'0';//倒叙存入数组 
	for(int i=0;i<lb;i++) b[i]=sb[lb-1-i]-'0';
	
	int t=0;//t进位 
	for(int i=0;i<N;i++){
		c[i]=a[i]+b[i]+t;
		t=c[i]/10;
		c[i]=c[i]%10;
	}
	
	int pos=N-1;
	while(c[pos]==0 and pos>0)pos--;
	
	for(int i=pos;i>=0;i--){
		cout<<c[i];
	} 
	return 0;
} 

高精度减法:

题目描述

求a−b 其中,a,b为两个不超过200位的非负整数,且a>b。

输入

有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。

输出

一行,即相减后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

样例输入:
999999999999999
99999
样例输出:
999999999900000

【源代码】:

#include <bits/stdc++.h>
using namespace std;
const int N=205;
int a[N],b[N],c[N];
int main(){
	string sa,sb;//看成字符串,防止数字超范围
	cin>>sa>>sb;
	int la=(int)sa.size();//sa字符串的长度 
	int lb=(int)sb.size();//sb字符串的长度 
	for(int i=0;i<la;i++) a[i]=sa[la-1-i]-'0';//倒叙存入数组 
	for(int i=0;i<lb;i++) b[i]=sb[lb-1-i]-'0';
	
	int t=0;//t是借位 
	for(int i=0;i<N;i++){
		c[i]=a[i]-b[i];
		if(c[i]<0){
			c[i]+=10;
			a[i+1]-=1;
		} 
	}
	
	int pos=N-1;
	while(c[pos]==0 and pos>0)pos--;
	
	for(int i=pos;i>=0;i--){
		cout<<c[i];
	} 
	return 0;
} 

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值