C语言正负大整数加减法(西电C程序作业1)

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

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

#include 
#include 
#include 
#define max(a,b) (a)>(b)?(a):(b)
const int MAX = 100;//最大存储位数
int mark = 1; //判定字符串转换为数组是是否产生错误
int length = 0;//记录答案的长度
int* add(int* num1 , int* num2,int len1, int len2);
int* decre(int* num1 , int* num2 , int len1 , int len2);
void swap(int* a, int* b);
void change(int *num , char* s);
int main(){
	char s1[100];
	char s2[100];
    int num1[100];
    
    int num2[100];
    char ch = '-';
    int len1 = 0, len2 = 0;
    memset(num1,0,sizeof(num1));
    memset(num2,0,sizeof(num2));
    printf("Please input num1:\n");
    scanf("%s",&s1);getchar();
    change(num1,s1);
    len1 = strlen(s1);
    if(s1[0] == '-')
    	len1--;
    if(mark == 0){
    	printf("Sorry ! Erroe input!");
    	return 0;
	}
    printf("Please intput operator(+ or -): \n");
    scanf("%c",&ch);getchar();
    if(ch != '+' && ch != '-'){
    	printf("Sorry ! Erroe input!");
    	return 0;
	}
    printf("Please input num2:\n");
    scanf("%s",&s2);getchar();
    change(num2,s2);
    len2 = strlen(s2);
    if(s2[0] == '-')
    	len2--;
    if(mark == 0){
    	printf("Sorry ! Erroe input!");
    	return 0;
	}
	puts(s1);
	printf("%c\n",ch);
	puts(s2);
	puts("Answer:");
	if(ch == '+'){
		int *ans = add(num1,num2,len1,len2);
		for(int i = 0; i < length; i ++){
			printf("%d",ans[i]);
		}
	}else{
		int *ans = decre(num1,num2,len1,len2);
		for(int i = 0; i < length; i ++){
			printf("%d",ans[i]);
		}
	}
    return 0;
}
void swap(int* a, int* b){
	int t = *a;
	*a = *b;
	*b = t;
}
//比较两个正整数的大小
int cmp(int* num1, int* num2, int len1 , int len2){
	if(len1 > len2){
		return 1;	//num1 > num2
	}else if(len2 > len1){
		return -1;	// num2 > num1
	}else{
		for(int i = 0; i < len1; i ++){
			if(num1[i] > num2[i])
				return 1;
			else if(num2[i] > num1[i])
				return -1;
		}
	}
	return 0;//相等
} 
int* add(int* num1 , int* num2,int len1, int len2){
	//符号相反 
	if(num1[0]*num2[0]<0){
	//找出其中的负数并返回减法的结果
		if(num1[0]<0){
			num1[0] = -num1[0];
			return decre(num2,num1,len2,len1);
		}else{
			num2[0] = -num2[0];
			return decre(num1,num2,len1,len2); 
		}
	}
	//负数相加时先将首位符号变为正,并使用flag标记
	int flag = 0;
	if(num1[0] < 0){
		flag = 1;
		num1[0] = -num1[0];
		num2[0] = -num2[0];
	}
    int maxlen = max(len1 , len2);
    int* ans = (int*)malloc(sizeof(int)*(maxlen+1));
    for(int i = 0; i <= maxlen ; i ++){
    	ans[i] = 0;
	}
	int i = len1-1;
	int j = len2-1;
	int k = 0;
	int las = 0;
	//模拟十进制加法并将结果倒序保存
	while(i >= 0 || j >= 0 || las != 0){
		if(i >= 0)
			las += num1[i--];
		if(j >= 0)
			las += num2[j--];
		ans[k++] = las%10;
		las /= 10;
	}
	i = 0;
	j = k-1;
	length = k;
	//反转数组
	while(i < j){
		swap(&ans[i++],&ans[j--]);
	}
	if(flag == 1)
		ans[0] = -ans[0];
	return ans;
}
//num1 - num2
int* decre(int* num1 , int* num2 , int len1 , int len2){
	if(num1[0]*num2[0] < 0){
		//符号相反
		num2[0] = -num2[0];
		return add(num1,num2,len1,len2);
	}else if(num1[0] == 0){//存在0
		num2[0] = -num2[0];
		length = len2;
		return num2;
	}else if(num2[0] == 0){//存在0
		length = len1;
		return num1;
	}
	//符号相同的情况
	if(num2[0]<0){	//负数 - 负数 -> 正数 - 正数
		num2[0] = -num2[0];
		return decre(num2,num1,len2,len1);
	}
	//到这里就只需考虑 正数 - 正数了
	if(cmp(num1,num2,len1,len2) < 0){ //小 - 大则改为 大-小
		int* res = decre(num2,num1,len2,len1);
		//将结果的符号修改为负
		res[0] = -res[0];
		return res;
	}else if( cmp(num1,num2,len1,len2)==0){//相同就立刻返回
		return {0};
	}
	int maxlen = max(len1 , len2);
	int* res = (int*)malloc(sizeof(maxlen));
	for(int i = 0; i < maxlen; i ++){
		res[i] = 0;
	}
	int i = len1-1;
	int j = len2-1;
	int k = 0;
	int las = 0;
	//模拟减法倒序记录
	while(j >= 0 || i >= 0 || las != 0){
		int tmp = num1[i--] + las;
		if(j >= 0)
			tmp -= num2[j--];
		las = tmp<0 ? -1:0;
		res[k++] = tmp>=0 ? tmp : tmp+10;
	}
	i = 0;
	j = k-1;
	//反转数组
	while(i<j){
		swap(&res[i++] , &res[j--]);
	}
	//除去前端多余的0操作
	int index = 0;
	while(res[index] == 0){
		index ++;
	}
	int t = index;
	for(int i = 0; index < k; i ++, index++){
		res[i] = res[index];
	}
	k -= t;
	length = k;
	return res;
}
void change(int *num , char* s){
	int len = strlen(s);
	int i = 0;
	int t = 0;
	if(s[0] == '-'){
		num[t++] = -(s[1] - '0');
		i = 2;
	}
	while(i < len){
		if(s[i]<'0' || s[i]>'9'){
			mark = 0;
			return ;
		}
		num[t++] = (s[i++]-'0');
	}
}

你可能感兴趣的:(随笔)