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

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

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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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');
	}
}
  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C语言中,可以使用GMP库来实现大整数加减乘除幂运算。下面是一个示例程序,演示了如何使用GMP库进行大整数运算: ``` c #include <stdio.h> #include <gmp.h> int main() { mpz_t a, b, c, d, e, f; mpz_init(a); mpz_init(b); mpz_init(c); mpz_init(d); mpz_init(e); mpz_init(f); // 加法 mpz_set_str(a, "123456789012345678901234567890", 10); mpz_set_str(b, "987654321098765432109876543210", 10); mpz_add(c, a, b); gmp_printf("a + b = %Zd\n", c); // 减法 mpz_set_str(a, "123456789012345678901234567890", 10); mpz_set_str(b, "987654321098765432109876543210", 10); mpz_sub(c, a, b); gmp_printf("a - b = %Zd\n", c); // 乘法 mpz_set_str(a, "123456789012345678901234567890", 10); mpz_set_str(b, "987654321098765432109876543210", 10); mpz_mul(c, a, b); gmp_printf("a * b = %Zd\n", c); // 除法 mpz_set_str(a, "123456789012345678901234567890", 10); mpz_set_str(b, "987654321098765432109876543210", 10); mpz_tdiv_q(c, a, b); gmp_printf("a / b = %Zd\n", c); // 幂运算 mpz_set_str(a, "123456789012345678901234567890", 10); mpz_set_ui(b, 10); mpz_pow_ui(c, a, 2); gmp_printf("a^2 = %Zd\n", c); mpz_clear(a); mpz_clear(b); mpz_clear(c); mpz_clear(d); mpz_clear(e); mpz_clear(f); return 0; } ``` 在这个示例程序中,我们分别演示了加法、减法、乘法、除法和幂运算。在每个运算中,我们都使用了`mpz_set_str`函数将字符串转换为大整数,使用相应的GMP库函数进行运算,最后使用`gmp_printf`函数输出结果。 需要注意的是,由于大整数运算需要分配大量的内存空间,因此在使用完毕后,需要使用`mpz_clear`函数释放这些内存空间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值