高精度计算

题目要求

涉及知识点:数组、流程控制、函数等
要求:用整型数组表示10进制大整数(超过2^32的整数),数组的每个元素存储大整数的一位数字,实现大整数的加减法。

题目解析

主体思路如下:
由于要求使用数组存储,首先使用字符串输入函数读取大整数,用数组的第一位存储正负符号。当输入的数据存在负数时,我们的想法便是将其转换为两个正数的加减。这样事实上只需要考虑正整数的加法和正整数的减法即可。

细节提示:

  1. 字符数组s中的字符转换为整型数组a中的数字。特别注意当大整数为负数时,字符数组中下标为0和下标为1的字符(s[0]和s[1]),一起转换存储到整型数组下标为0的单元(a[0]) 。 a[0]=-(s[1]-‘0’)
  2. 两个大整数相加时,分情况处理:
    两个大整数符号相反。比如负数+正数或者正数+负数,调用两个大整数相减的函数。
    两个大整数符号相同。比如负数+负数或者正数+正数。先对负数+负数的情况做处理,把两个大整数的负号去掉,转换为正数+正数的情况,按正数+正数的情况计算结果,最后结果再加上负号;然后对于正数+正数的情况,从个位开始模拟十进制加法并将结果倒序保存在另一个整型数组中;最后将倒序结果转为顺序。
  3. 两个大整数相减时,分情况处理:
    ①两个大整数符号相反。把第二个大整数的符号取反,然后调用两个大整数相加的函数。
    ②两个大整数中存在某个数为0的情况。
    ③两个大整数符号相同。
    第一种情况:负数-负数的情况,转换为正数-正数。
    第二种情况:正数-正数。先比较两个正大整数的大小,如果小-大,改为大-小,结果加上负号;如果相等,返回0;如果大-小,从个位数开始模拟十进制减法,并将结果倒序保存到另一个整型数组中,要注意是否高位要借位,也就是是否需要-1,本位结果如果为负数需要+10,并把高一位-1。

代码实现

#include<stdio.h>
#include<string.h>
int Positive(char s1[],char s2[],char math[],int len1,int len2,int n,int t)
{
	int num[1001]={0},num1[1000]={0},num2[1000]={0}; //存储转换后的整形数字 
	int count=0;//用于比较同位数时,两个数字的大小 
	if(len1>len2){n=len1;}
	else if(len1<len2){n=len2;t=1;}
	else if(len1==len2){n=len1;t=2;} //为下面输出计算完成后的数字做准备 
	//printf("%d\n",t); //检验t是否正确 

	
	for(int i=0,j=len1-1;i<len1,j>=0;i++,j--){
		num1[i]=s1[j]-'0';
	}
	for(int i=0,j=len2-1;i<len2,j>=0;i++,j--){
		num2[i]=s2[j]-'0';
	}//数据转换 
	
	if(math[0]=='+'){
		for(int i=0;i<n;i++){
			num[i]=num1[i]+num2[i];
		}
		for(int i=0;i<n;i++){
			if(num[i]>=10){
				num[i]-=10;
				num[i+1]++;
			}
		}//进行运算 
		
		if(num[n]!=0){
			for(int i=n;i>=0;i--){
				printf("%d",num[i]);
			}
		}
		else{
			for(int i=n-1;i>=0;i--){
				printf("%d",num[i]);
			}
		}//倒序输出
	}//case1.1:正整数相加 
	
	else if(math[0]=='-'&&t==0){
		for(int i=0;i<n;i++){
			num[i]=num1[i]-num2[i];
		}
		for(int i=0;i<n;i++){
			if(num[i]<0){
				num[i]=num[i]+10;
				num[i+1]--;
			}
		}//进行运算 
		if(num[n-1]!=0){
			for(int i=n-1;i>=0;i--){
				printf("%d",num[i]);
			}
		}
		else{
			for(int i=n-2;i>=0;i--){
				printf("%d",num[i]);
			}
		}//倒序输出 
	}//case1.2.1:正整数相减(位数大减位数小) 
	
	else if(math[0]=='-'&&t==1){
		for(int i=0;i<n;i++){
			num[i]=num2[i]-num1[i];
		}
		for(int i=0;i<n;i++){
			if(num[i]<0){
				num[i]=num[i]+10;
				num[i+1]--;
			}
		}//进行运算 
		
		printf("-");
		if(num[n-1]!=0){
			for(int i=n-1;i>=0;i--){
				printf("%d",num[i]);
			}
		}
		else{
			for(int i=n-2;i>=0;i--){
				printf("%d",num[i]);
			}//倒序输出 
		}
	}//case1.2.2:正整数相减(位数小减位数大) 
	
	else if(math[0]=='-'&&t==2){
		for(int i=0;i<n;i++){
			if(s1[i]>s2[i]){
				count=0;break;
			}
			else if(s1[i]<s2[i]){
				count=1;break;
			}
			else count=2;
		}//用于比较同位数时,两个数字的大小
		
		if(count==2){
			printf("0"); 
		}//case1.3.1:两个数字大小相同 
		
		else if(count==0){
			for(int i=0;i<n;i++){
				num[i]=num1[i]-num2[i];
			}
			for(int i=0;i<n;i++){
				if(num[i]<0){
					num[i]=num[i]+10;
					num[i+1]--;
				}
			}//进行运算 
			int flag=0;	
			for(int i=n;i>=0;i--){
				if(num[i]==0){
					flag++;
				}
				else break;
			}
			for(int i=n-flag;i>=0;i--){
				printf("%d",num[i]);
			}//倒序输出   //case1.3.2:大减小 
		}
		
		else if(count==1){
			for(int i=0;i<n;i++){
				num[i]=num2[i]-num1[i];
			}
			for(int i=0;i<n;i++){
				if(num[i]<0){
					num[i]=num[i]+10;
					num[i+1]--;
				}
			}//进行运算 
			
			printf("-");
			if(num[n-1]!=0){
				for(int i=n-1;i>=0;i--){
					printf("%d",num[i]);
				}
			}
			else{
				for(int i=n-2;i>=0;i--){
					printf("%d",num[i]);
				}//倒序输出  //case1.3.3:小减大 
			} 
		}
	}//case1.3:正整数相减(位数相同) 
	return 0;
}

int Negative(char s1[],char s2[],char math[],int len1,int len2,int n,int t)
{
	if(len1>len2){n=len1;}
	else if(len1<len2){n=len2;t=1;}
	else if(len1==len2){n=len1;t=2;} //为下面输出计算完成后的数字做准备 
		
	char temp1[1000]={0},temp2[1000]={0};
	int l1=len1-1,l2=len2-1;
	
	for(int i=0;i<l1;i++){
		temp1[i]=s1[i+1];
	} 
	for(int i=0;i<l2;i++){
		temp2[i]=s2[i+1];
	}//舍去负号,转存新数组 
	
	if(math[0]=='+'){
		printf("-");
		Positive(temp1,temp2,math,l1,l2,n,t);//转换为正整数相加 
	}//case2.1:负整数相加 
	
	char tmath[2];tmath[0]='-'; int tn=0,tt=0;
	if(l2>l1){
		tn=l2;
	}
	else if(l2<l1){tn=l1;tt=1;}
	else if(l2==l1){tn=l1;tt=2;}//将两个负数相减转换为正数减负数 
	if(math[0]=='-'){
		Positive(temp2,temp1,tmath,l2,l1,tn,tt);
	}//case2.2:负整数相减 
}//负数做加减 


int PandN(char s1[],char s2[],char math[],int len1,int len2,int n,int t)
{	
	char temp[1000];
	for(int i=0;i<len2-1;i++){
		temp[i]=s2[i+1];
	}//数组舍弃负号 
	
	char tmath[2];int l2=len2-1;
	if(len1>l2){n=len1;t=0;}
	else if(len1=l2){n=len1;t=2;}
	else if(len1<l2){n=len2;t=1;}
	
	if(math[0]=='+'){
		tmath[0]='-';
		Positive(s1,temp,tmath,len1,l2,n,t);
	}//正数加负数,转化为正数减正数 
	
	else if(math[0]=='-'){
		tmath[0]='+';
		Positive(s1,temp,tmath,len1,l2,n,t);
	}//正数减负数,转化为正数加正数 
}

int main()
{
	char s1[1000],s2[1000],math[2];
	printf("请输入第一个数字\n"); scanf("%s",s1);
	printf("请输入运算符 +/-\n"); scanf("%s",math);
	printf("请输入第二个数字\n"); scanf("%s",s2); //读取数字和运算方式 

	int len1,len2;
	len1=strlen(s1);len2=strlen(s2); //为数据转换做准备
	//printf("%d %d\n",len1,len2);//检验len1和len2是否正确 
	
	int n;//printf("%d\n-------------\n",n);//检验n是否正确
	int t=0;//两个数都是正数时,用于判断位数 
	char temp[1000];temp[0]='-';//case3.2.2中转换负数减正数为负数加负数时使用 
	
	if(s1[0]=='0'&&s2[0]=='0') {printf("0");}//0加0 
	else if(s1[0]=='0'&&math[0]=='+'&&s2[0]=='-'){
		printf("-");
		for(int i=1;i<len2;i++){
			printf("%d",s2[i]-'0');
		}
	}//0加负数 
	
	else if(s1[0]=='0'&&math[0]=='-'&&s2[0]=='-'){
		for(int i=1;i<len2;i++){
			printf("%d",s2[i]-'0');
		}
	}//0减负数 
	
	else if(s2[0]=='0'&&math[0]=='+'&&s1[0]=='-'){
		printf("-");
		for(int i=1;i<len1;i++){
			printf("%d",s1[i]-'0');
		}
	}//负数加0 
	
	else if(s2[0]=='0'&&math[0]=='-'&&s1[0]=='-'){
		printf("-");
		for(int i=1;i<len1;i++){
			printf("%d",s1[i]-'0');
		}
	}//负数减0 
	//0和数字相加减 
	
	else if(s1[0]!='-'&&s2[0]!='-'){
		Positive(s1,s2,math,len1,len2,n,t);
	}//case1:两个正数做加减 
	
	else if(s1[0]=='-'&&s2[0]=='-'){
		Negative(s1,s2,math,len1,len2,n,t);
	}//case2:两个负数做加减
	
	else if(s1[0]!='-'&&s2[0]=='-'){
		PandN(s1,s2,math,len1,len2,n,t);
	}//case3.1:正数在前,负数在后 
	
	else if(s2[0]!='-'&&s1[0]=='-'&&math[0]=='+'){
		int m=len1;len1=len2;len2=m;
		PandN(s2,s1,math,len1,len2,n,t);
	}//case3.2.1:负数在前,正数在后(加法)
	
	else if(s2[0]!='-'&&s1[0]=='-'&&math[0]=='-'){
		math[0]='+';len2=len2+1;
		for(int i=1;i<len1+1;i++){
			temp[i]=s2[i-1];
		}
		Negative(s1,temp,math,len1,len2,n,t);
	}
	//case3:正数和负数做加减 
	return 0;
}

总共写了三个子函数,Negative是两个负数进行计算,Positive是两个正数进行计算,PandN是一个负数和一个正数。
剩下的解释在代码中应该都有注释,可能变量名字比较多比较复杂2333,反正我写的时候差点眼花

代码有些长了…主要还是因为我菜,大伙将就着看…
据听说有只写了几十行的…球球大佬别骂我…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值