高精度运算

高精度运算

高精度加减

1.主要处理高精度加减之流的问题,其思路大致为字符数组读入→ASCII转换→对应位数加减→处理进位,代码如下:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
char sa[210],sb[210];
int la,lb,lc,a[210],b[210],c[210];        //范围自取
int main(){
	scanf("%s",sa);
	scanf("%s",sb);
	la=strlen(sa);
	lb=strlen(sb);
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	for(int i=0;i<la;i++){        //char与int转化
		a[la-i-1]=sa[i]-'0';
	}
	for(int i=0;i<lb;i++){
		b[lb-i-1]=sb[i]-'0';
	}
	lc=la>lb ?la: lb;        //确定结果位数上限
	memset(c,0,sizeof(c));
	for(int i=0;i<lc;i++){
		c[i]=a[i]-b[i]+c[i];
		if(c[i]<0){        //处理进位(借位)
			c[i+1]-=1;
			c[i]+=10;
		}
	}
	if(c[lc]<0)	lc--;
	for(int i=lc-1;i>=0;i--){        //使结果最高位非零
		if(c[i]==0)	lc--;
		else	break;
	}
	for(int i=lc-1;i>=0;i--){
		printf("%d",c[i]);
	}
	return 0;
}

2.​斐波那契数列问题涉及模运算有关性质:(a+b)%p=(a%p+b%p)%p。可以避免超出long long的情况,代码如下:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,t[1000010],a[1000010];
int main(){
	cin>>n;
	memset(t,0,sizeof(t));
	memset(a,0,sizeof(a));
	for(int i=1;i<=n;i++){
		cin>>t[i];
	}
	a[1]=1;
	a[2]=1;
	for(int i=3;i<=1000010;i++){
		a[i]=((a[i-1]%1000)+(a[i-2]%1000))%1000;        //控制单个数据大小
	}
	for(int i=1;i<=n;i++){
		cout<<a[t[i]]%1000<<endl;
	}
	return 0;
}

高精度乘除

基本步骤同上,但必须考虑进位与最高位问题,进位需使用单独变量,代码如下:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
long long la,lb,lc,x[20010],y[20010],z[20010],w,jw,f;        //注意数据大小
char a[20010],b[20010];
int main(){
	scanf("%s",a);
	scanf("%s",b);
	la=strlen(a);
	lb=strlen(b);
	memset(x,0,sizeof(x));
	memset(y,0,sizeof(y));
	memset(z,0,sizeof(z));
	for(int i=0;i<la;i++)	x[la-i-1]=a[i]-'0';
	for(int i=0;i<lb;i++)	y[lb-i-1]=b[i]-'0';
	for(int i=0;i<la;i++){
		for(int j=0;j<lb;j++){
			f=x[i]*y[j];        //f:记录结果
			jw=f/10;        //jw:记录进位
			f%=10;
			w=i+j;        //w:每次数组的下标
			z[w]+=f;
			z[w+1]+=jw+z[w]/10;//处理进位
			z[w]%=10;
		}
	}
	lc=la+lb;
	while(z[lc]==0)	lc--;
	if(lc<0)	printf("%d",0);
	else{
		for(int i=lc;i>=0;i--)	printf("%lld",z[i]);
	}
	return 0;
}
posted @ 2022-11-09 12:17  Nebulary  阅读(14)  评论(0编辑  收藏  举报