高精度加减法的实现

高精度加减法(大整数加减法)

1.使用字符数组存储输入的两个大整数,此时字符数组序号的低位对应着大整数的高位
2.将字符数组中的各位数字字符转换为数字,逆序存储在另一个整型数组里边,这时,数字的低位对应着字符数组的序号低位(即数字的各位存储在字符数组的第0位)
3.之后便可以进行大整数相加与相减了,不过相加注意进位,相减注意借位
4.相减运算需要进行大整数大小比较,用到了strlen与strcmp函数
5.以上建立在两个大整数都是正数的情况下,不过若不限制正负数,其实也只是多一些组合罢了,具体实现代码如下

高精度加减法的代码实现

题目要求:用整形数组表示10进制大整数,数组的每个元素存储大整数的一位数字,实现大整数的加减法

下面是 高精度加减法的实现,仅供参考。

//用整形数组表示10进制大整数,数组的每个元素存储大整数的一
//位数字,实现大整数的加减法
#include <stdio.h>
#include <string.h>

int main() {
	void forward(char arr[]);
	void addResult(int addLen, int addAnswer[]);
	void minusResult(int flag, int minusLen, int minusAnswer[]);
	void minusResultSwitch(int flag, int minusLen, int minusAnswer[]) ;

	int bigInteger_1[20] = {0};//存放大整数1,数字低位对应数组序号低位
	int bigInteger_2[20] = {0};//存放大整数2,数字低位对应数组序号低位
	int addAnswer[20] = {0};//存放加法结果,数字低位对应数组序号高位
	int minusAnswer[20] = {0};存放减法结果,数字低位对应数组序号高位
	char number_1[20] = {'\0'};//存放大整数1,数字高位对应数组序号低位
	char number_2[20] = {'\0'};//存放大整数2,数字高位对应数组序号低位

	printf("请输入两个大整数:\n");
	scanf("%s %s", number_1, number_2);//输入两个大整数字符串

	int key;//四种输入情况
	if (number_1[0] != '-' && number_2[0] != '-') {//++
		key = 1;
	} else if (number_1[0] == '-' && number_2[0] == '-') {//--
		key = 2;
	} else if (number_1[0] == '-' && number_2[0] != '-') {//-+
		key = 3;
	} else if (number_1[0] != '-' && number_2[0] == '-') {//=-
		key = 4;
	}

	switch (key) {//修正number,使之变为可计算的(即没有负号)
		case 1:
			break;
		case 2:
			forward(number_1);
			forward(number_2);
			break;
		case 3:
			forward(number_1);
			break;
		case 4:
			forward(number_2);
			break;
	}


	int i, j;//将数字以字符数组存储改为以整形数组存储,逆序存储,使得数字低位对应数组序号高位,便于下一步操作
	for (i = 0, j = strlen(number_1) - 1; j >= 0; i++, j--) {
		bigInteger_1[i]
		    = number_1[j] - '0';
	}
	for (i = 0, j = strlen(number_2) - 1; j >= 0; i++, j--) {
		bigInteger_2[i]
		    = number_2[j] - '0';
	}

	int len = strlen(number_1) > strlen(number_2) ? strlen(number_1) : strlen(number_2); //确定最大数字的长度

	//大整数加法的实现
	//1.相加的实现
	for (i = 0; i < len + 1; i++) { //le+1的原因:相加结果数字长度最多比最大整数长度多一
		int ans = bigInteger_1[i]
		          + bigInteger_2[i];//相加结果的记录,进一步判断是否需要进位

		if (ans >= 10) { //发生了进位情况,结果当前位置值应该是ans-10,并且高一位应该进一
			ans -= 10;
			addAnswer[i + 1] += 1;
			addAnswer[i] += ans;
		} else { //没有发生进位情况
			addAnswer[i] += ans;
		}

		if (addAnswer[i] >= 10) {
			addAnswer[i] -= 10;
			addAnswer[i + 1] += 1;
		}
	}
	//2.求得最终结果的位数(因为最终结果长度==len或者==len+1)
	int addLen = 0;//顾全0+0=0这一情况,就当做是0位数喽,因为需要通过最高位是否为零来判断最终结果的位数
	for (i = len; i >= 0; i--) {
		if (addAnswer[i] != 0) {
			addLen = i + 1;
			break;
		}
	}
	//3.相加结果的输出(从高位进行输出)
//	printf("大整数相加的结果为:");
//	addResult( addLen, addAnswer);

	//大整数减法的实现
	//1.正负判断,flag>0表示正数,<0表示负数,=0表示差值为零
	int flag;
	if (strlen(number_1) > strlen(number_2)) {//长度判断,被减数长度长则差值大于零
		flag = 1;
	} else if (strlen(number_1) == strlen(number_2)) {//长度相同则进行数字大小判断
		if (strcmp(number_1, number_2) > 0) {
			flag = 1;
		} else if (strcmp(number_1, number_2) == 0) {
			flag = 0;
		} else {
			flag = -1;
		}
	} else {//被减数长度长则差值小于零
		flag = -1;
	}
	//2.减法运算的实现(flag==0的情况结果直接为零)
	if (flag > 0) {
		for (i = 0; i < len; i++) {//减法运算的结果位数最大为最大整数的位数


			int ans = bigInteger_1[i] - bigInteger_2[i];

			if (ans < 0) {//减不下需要借位:相减结果小于零要借位
				ans += 10;
				minusAnswer[i] += ans;
				minusAnswer[i + 1] -= 1;
			} else {
				minusAnswer[i] += ans;
			}

			if (minusAnswer[i] < 0) {//相减结果大于零但是当前位因为借位变负,要借位
				minusAnswer[i] += 10;//注意不能放for循环首行,
				minusAnswer[i + 1] -= 1;
			}
		}
	} else if (flag < 0) {
		for (i = 0; i < len; i++) {
			int ans = bigInteger_2[i] - bigInteger_1[i];

			if (ans < 0) {
				ans += 10;
				minusAnswer[i] += ans;
				minusAnswer[i + 1] -= 1;
			} else {
				minusAnswer[i] += ans;
			}

			if (minusAnswer[i] < 0) {
				minusAnswer[i] += 10;
				minusAnswer[i + 1] -= 1;
			}
		}
	}

	//3.寻找到最终结果的最高为的位数
	int minusLen = 0;
	for (i = len - 1; i >= 0; i--) {
		if (minusAnswer[i] != 0) {
			minusLen = i + 1;
			break;
		}
	}

	//4.大整数相减结果的输出
//	printf("\n大整数的相减的结果为:");
//	minusResult( flag,  minusLen,  minusAnswer);

	//end
	switch (key) {
		case 1:
			printf("和:");//a+b
			addResult( addLen, addAnswer);
			printf("\n差:");//a-b
			minusResult( flag,  minusLen,  minusAnswer);
			break;
		case 2:
			printf("和:-");//-a-b
			addResult( addLen, addAnswer);
			printf("\n差:");//-a+b
			minusResultSwitch( flag,  minusLen,  minusAnswer);
			break;
		case 3:
			printf("和:");//-a+b
			minusResultSwitch( flag, minusLen,  minusAnswer);
			printf("\n差:-");//-a-b
			addResult( addLen, addAnswer);
			break;
		case 4:
			printf("和:");//a-b
			minusResult( flag,  minusLen,  minusAnswer);
			printf("\n差:");//a+b
			addResult( addLen, addAnswer);
			break;
	}


	return 0;

}

void forward(char arr[]) {//删除负号的作用
	int i = 0;
	for (i = 0; i < strlen(arr); i++) {
		arr[i] = arr[i + 1];
	}
}

void addResult(int addLen, int addAnswer[]) {
	int i = 0;
	if (addLen == 0) {
		printf("0");
	} else {
		for (i = addLen - 1; i >= 0; i--) {
			printf("%d", addAnswer[i]);
		}
	}
}

void minusResult(int flag, int minusLen, int minusAnswer[]) {
	int i = 0;
	if (flag == 0) {
		printf("0");
	} else if (flag > 0) {
		for (i = minusLen - 1; i >= 0; i--) {
			printf("%d", minusAnswer[i]);
		}
	} else  {
		printf("-");
		for (i = minusLen - 1; i >= 0; i--) {
			printf("%d", minusAnswer[i]);
		}
	}
}

void minusResultSwitch(int flag, int minusLen, int minusAnswer[]) {

	int i = 0;
	if (flag == 0) {
		printf("0");
	} else if (flag > 0) {
		printf("-");
		for (i = minusLen - 1; i >= 0; i--) {
			printf("%d", minusAnswer[i]);
		}
	} else  {

		for (i = minusLen - 1; i >= 0; i--) {
			printf("%d", minusAnswer[i]);
		}
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值