高精度

本文介绍了在数字运算中遇到长整数时如何使用高精度算法。通过三个例题,分别展示了高精度加法、减法和乘法的实现,并提供了代码示例。此外,还提及了高精度乘法和除法的解题思路,以及高精度与单精度数的混合运算。文章强调了高精度算法的重要性和使用时需要注意的时间复杂度问题。
摘要由CSDN通过智能技术生成

引入

在数字运算中,有时候a*b连long long 都装不下,这个适合,就需要用到高精度了。

例题1

P2955 [USACO09OCT]Even? Odd? G

分析

判断一个数的奇偶,即判断能否被2整除,其实也就只需要判断末位数字是否为2的倍数。

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++){
		char a[65];scanf("%s",a);//long long装不下,用字符串 
		int c=strlen(a);
		int s=a[c-1]-'0';//求末位数字 
		if(s%2==0)printf("even\n");//判断整除 
		else printf("odd\n");
	}
}

例题2

题目描述
输入长度(超过14,小于99)的两个正数,输出两个数的和。

输入
两行
第一行,一个数
第二行,一个数

输出
一行
输入的两个数的和

样例输入
900000000000000
1111111111111111
样例输出
2011111111111111

分析

这道题一看,即使看long long 也一定会爆精度,但我们可以参考例题1的方法,用字符串存数,进行字符串运算。也就是高精度加法。

代码

#include<bits/stdc++.h>
using namespace std;
#define N 100+5
#define INF 0x3f3f3f3f
#define full(a,b) memset(a,b,sizeof a)
void init(int x[]){
	string s;cin>>s;
	x[0]=s.size();
	for(int i=1;i<=x[0];i++)
	x[i]=s[x[0]-i]-'0';//转化为数字,并且逆序储存 
}
int main(){
	int a[N],b[N],c[N];
	full(a,0);full(b,0);full(c,0);//记得初始化 
	init(a);init(b);//输入 
	
	int pos=1,x=0;
	while(pos<=a[0]||pos<=b[0]){
		c[pos]=a[pos]+b[pos]+x;
		x=c[pos]/10;
		c[pos]%=10;
		++pos;
	}c[pos]=x,c[0]=pos;//高精度加法模板 
	
	while(c[0]>1&&c[c[0]]==0)c[0]--;//去掉前导0 
	for(int i=c[0];i>=1;i--)//逆序输出 
	printf("%d",c[i]);
}

例题3

P2142 高精度减法

分析

题目已经暴露了一切,就直接上代码了。

代码

#include<bits/stdc++.h>
using namespace std;
#define N 100+5
#define INF 0x3f3f3f3f
#define full(a,b) memset(a,b,sizeof a)
void init(int x[]){//读入 
	char s[N];cin>>s;
	x[0]=strlen(s);
	for(int i=1;i<=x[0];i++)
	x[i]=s[x[0]-i]-'0';
}
int numcmp(int x[],int y[]){//比较大小 
	if(x[0]<y[0])return -1;
	if(x[0]>y[0])return 1;
	for(int i=x[0];i>=1;i--)
	if(x[i]>y[i])return 1;
	else if(x[i]<y[i])return -1;
	return 0;
}
void numcpy(int x[],int y[],int pos){//把x赋值给y,并把y乘 10的pos次方 
	y[0]=x[0]+pos-1;
	for(int i=1;i<=x[0];i++)
	y[i+pos-1]=x[i];
}
int main(){
	int a[N],b[N];
	full(a,0);full(b,0);//记得初始化 
	init(a);init(b);
	if(numcmp(a,b)<0){//a比b小 
		int k[N];
		full(k,0);numcpy(a,k,1);
		full(a,0);numcpy(b,a,1);
		full(b,0);numcpy(k,b,1);//交换两数 
		cout<<"-";//结果为负数 
	}
	int i=1;
	while(i<=a[0]){
		if(a[i]<b[i])a[i]+=10,a[i+1]--;
		a[i]-=b[i];++i;
	}//高精度减法模板 
	
	while(a[0]>1&&a[a[0]]==0)a[0]--;
	for(int i=a[0];i>=1;i--)
	printf("%d",a[i]);
}

高精度乘法

题目描述
输入两个高精度非负整数m和n(m和n均小于100位),求这两个高精度数的积。

输入
输入两个高精度正整数m和n(m和n均小于100位)

输出
输出两个高精度数的积

样例输入
36
3
样例输出
108

代码

#include<bits/stdc++.h>
using namespace std;
#define N 100+5
#define INF 0x3f3f3f3f
#define full(a,b) memset(a,b,sizeof a)
void init(int x[]){//读入 
	char s[N];cin>>s;
	x[0]=strlen(s);
	for(int i=1;i<=x[0];i++)
	x[i]=s[x[0]-i]-'0';
}
int main(){
	int a[N],b[N],c[N];
	full(a,0);full(b,0);full(c,0);
	init(a);init(b);
	
	for(int i=1;i<=a[0];i++){
		int x=0;
		for(int j=1;j<=b[0];j++){
		c[i+j-1]+=a[i]*b[j]+x;
		x=c[i+j-1]/10;
		c[i+j-1]%=10;
		}c[i+b[0]]+=x;
	}c[0]=a[0]+b[0];
	//模板 
	while(c[0]>1&&c[c[0]]==0)c[0]--;
	for(int i=c[0];i>=1;i--)
	printf("%d",c[i]);
}

高精度除法

P2005 A/B Problem II

代码

#include<bits/stdc++.h>
using namespace std;
#define N 100000+5
#define INF 0x3f3f3f3f
#define full(a,b) memset(a,b,sizeof a)
#define gaoji(x) while(x[0]>1&&x[x[0]]==0) --x[0];//去前导0 
void init(int x[]){//读入 
	char s[N];cin>>s;
	x[0]=strlen(s);
	for(int i=1;i<=x[0];i++)
	x[i]=s[x[0]-i]-'0';
}
void numcpy(int x[],int y[],int pos){//数组的拷贝 
	y[0]=x[0]+pos-1;
	for(int i=1;i<=x[0];i++)
	y[i+pos-1]=x[i];
}
int numcmp(int x[],int y[]){//比较大小 
	if(x[0]>y[0])return 1;
	if(x[0]<y[0])return -1;
	for(int i=x[0];i>=1;i--)
	if(x[i]>y[i])return 1;
	else if(x[i]<y[i])return -1;
	return 0;
}
void jian(int x[],int y[]){//减法 
	int k=1;
	while(k<=x[0]){
		if(x[k]<y[k])x[k]+=10,x[k+1]--;
		x[k]-=y[k];++k;
	}
	gaoji(x);
}
void print(int a[])//输出 
{
	if(a[0]<=0) printf("0");
	for(int i=a[0];i>=1;i--)
		printf("%d",a[i]);
	puts("");
}
int main(){
	int a[N],b[N],c[N];
	full(a,0);full(b,0);full(c,0);
	init(a);init(b); 
	
	c[0]=a[0]-b[0]+1;
	for(int k=c[0];k>=1;k--){
		int tmp[N];
		full(tmp,0);
		numcpy(b,tmp,k);//末位对齐 
		while(numcmp(a,tmp)>=0)
		{c[k]++;jian(a,tmp);}//除法变减法 
	}
	//模板 
	gaoji(c);
	print(c);
}

高精*单精

void cheng(int a[],int x)//a*x
{
	for(int i=1; i<=a[0]; i++) a[i]*=x;//先乘 
	for(int i=1; i<=a[0]; i++)
	{
		a[i+1]+=a[i]/10;//再加 
		a[i]%=10;
	}
	++a[0];//可能进位 
	while(a[a[0]]>9)//处理进位 
	{
		a[a[0]+1]+=a[a[0]]/10;
		a[a[0]]%=10;
		++a[0];
	}
	gaoji(a);
}

高精/单精

void chu(int a[],int x)//a/x
{
	for(int i=a[0]; i>=1; i--)//从高到低除 
	{
		if(i>1) a[i-1]+=a[i]%x*10;//第0位不改变 
		a[i]/=x;
	}
	gaoji(a);
}

总结

高精度在很多时候都起到了作用,是一个很可恶的优秀的算法,但是高精度太频繁也会时间超限,要谨慎使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值