高精度整数的(+,-,*)

高精度整数加法问题

求两个整数,a和b的和,(0=<a,b<=1e500)
高精度整数是个什么?
高精度整数就是超过整数类型(long long目前我学习到的最大整数类型)的正数,例如1e23+1e25等于多少?显然用long long也不够装,所以我们就要用字符串来处理。先来看看一个简单的例子999+111=?

    999
   +111
  =1110
思路

这就需要回想起小学我们学的加减法了,借位(-)与进位(+)问题,分三个步骤来求解:
1.处理输入:用两个字符数组来保存a和b,ans数组表示最终答案
2.运算过程:遍历两个字符数组,算出结果的每一位数,ans[i]+=a[i]+b[i]-2*‘0’(这里要分开+,如果不分开+会出现意想不到的结果哦,分开加是为了避免加到的是-‘0’而不是0,会影响起结果);
如果ans[i]>9,则进位(ans[i+1]++,ans[i]%=10)
3.处理输出:输出要注意的就是答案不包含前导0的情况。

代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=505;
char a[MAXN],b[MAXN];
int ans[MAXN];
int main(){
	scanf("%s%s",&a,&b);
	int lena=strlen(a);
	int lenb=strlen(b);
	reverse(a,a+lena);
	reverse(b,b+lenb);//反转两数组从个位算起 
	int n=max(lena,lenb);
	for(int i=0;i<n;i++){
		if(i<lena)	ans[i]+=a[i]-'0';
		if(i<lenb)	ans[i]+=b[i]-'0';
		if(ans[i]>9){//进位 
			ans[i]=ans[i]%10;
			ans[i+1]+=1;
		}
	}
	if(ans[n]!=0)	printf("%d",ans[n]);
	for(int i=n-1;i>=0;i--)	printf("%d",ans[i]);
	return 0;
}
高精度整数减法问题

求两个整数 a,b的差(第二个可能比第一个大,0=<a,b<=10086)。

思路

1.处理输入:输入两个字符串,我们后期算的时候就用大的数减小的数
这里尤其关键,举个例子234-345=?

    234
   -345
  =-289

这是我算的,哈哈,我都不知道是怎么算的,最高位不够减我是怎么借来的,当时估摸着不对啊,口算也是-111啊,怎么就算到-289了,就发现问题所在了,我们只需要处理输入,每次将大的数赋给a,小的给b,然后用a-b来算,然后做个标记,如果交换则,最后输出一个负号即可,判断大小具体在代码里面。
2.运算过程:遍历两个字符数组,算出结果的每一位数,
ans[i]-=a[i]+b[i]-2*‘0’(这里要分开-,如果不分开-会出现意想不到的结果哦,分开加是为了避免减到的是-‘0’而不是0,会影响起结果);
如果ans[i]<0,则借位(ans[i+1]–,ans[i]+=10)
3.处理输出:还是前导0的情况。

代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=10086+5;
char a[MAXN],b[MAXN];
int ans[MAXN];
int main(){
	int flag=false;
	scanf("%s%s",&a,&b);
	int lena=strlen(a);
	int lenb=strlen(b); 
	if(lenb>lena||(lena==lenb&&strcmp(a,b)<0)){
		swap(a,b);
		flag=true;//始终是大的减去小的,如果交换了,则最后加负号 
	}
	lena=strlen(a);
	lenb=strlen(b); 
	reverse(a,a+lena);
	reverse(b,b+lenb);
	for(int i=0;i<lena;i++){
		if(i<lena)	ans[i]+=a[i]-'0';
		if(i<lenb)	ans[i]-=b[i]-'0';
		if(ans[i]<0){//借位 
			ans[i]+=10;
			a[i+1]--;
		}
	}
	int i=lena-1;
	if(flag)	printf("-"); 
	while(ans[i]==0&&i>0) i--;//这里要留个位给最后的输出,万一等于0呢。 
	for(int j=i;j>=0;j--)	printf("%d",ans[j]); 
	return 0;
}
  
高精度整数乘法问题

求两数的积。(0=<a,b<=1e2000)

思路

1.处理输入:用两个字符数组来保存a和b,ans数组表示最终答案;
2.运算过程:还是小学知识

    999
   * 99
  =98901

我们先算999* 9,其原理和加法类似(ans[j]+=(a[j]-‘0’)(b[i]-‘0’)),如果ans[j]>9,则还是加到高一位去ans[j+1]=ans[j]/10;ans[j]%=10,然后算90 * 999=>9 999*10,我们可以这样处理,a数组遍历完一次了过后,则最低位加一位,然后继续进行乘法操作;
3.处理输出:前导0。

代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=2e3+5;
char a[MAXN],b[MAXN];
int ans[MAXN<<1];
int main(){
	scanf("%s%s",&a,&b);
	int lena=strlen(a);
	int lenb=strlen(b);
	reverse(a,a+lena);
	reverse(b,b+lenb);
	int k=0;
	for(int i=0;i<lenb;i++){
		for(int j=0;j<lena;j++){
			int index=j+k;
			ans[index]+=(b[i]-'0')*(a[j]-'0');
			if(ans[index]>9){
				ans[index+1]+=ans[index]/10;
				ans[index]=ans[index]%10;
			}
		}
		k++;
	}
	int i=lena+lenb-1;
	while(ans[i]==0&&i>0) i--;//a*b最大lena+lenb位数,最小lena+lenb-1位数 
	for(int j=i;j>=0;j--)	printf("%d",ans[j]);
	return 0;
}

当然,具体问题具体分析,假如a和b包含负数加一些判断即可,下面的绝对值可不是真正的绝对值,只是去掉-,将原数组拷贝到新数组中:
1.a+b:
a>0,b<0=>a-|b|;
a<0,b>0=>b-|a|;
a<0,b<0=>-(|a|+|b|);
a>0,b>0=>a+b;
2.a-b:
a>0,b<0=>a+|b|;
a<0,b>0=>-(b+|a|);
a<0,b<0=>b-a;
a>0,b>0=>a-b;
3.a*b:
a>0,b<0=>-a * |b|;
a<0,b>0=>-b * |a|;
a<0,b<0=>|a| * |b|;
a>0,b>0=>a * b;

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空皓月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值