C语言实现大数相加相减和相乘

首先是字符串翻转函数,大数相加、相减和相乘中都用到了这个函数

/*
** 字符串翻转
*/
void Reverse(char *str, int n)
{
	int i;

	for (i = 0; i < n / 2; i++)
	{
		char tmp;
		tmp = str[i];
		str[i] = str[n-i-1];
		str[n-i-1] = tmp;
	}
}

1.大数相加

/*
** 这里假设str1和str2表示的数为非负数
*/
void BigNumAdd(char *str1, char *str2, char *result)
{
	if (str1 == NULL || str2 == NULL || result == NULL)
	{
		return;
	}
	int len1, len2;

	len1 = strlen(str1);
	len2 = strlen(str2);

	Reverse(str1, len1);			// 将str1翻转
	Reverse(str2, len2);			// 将str2翻转

	int weight = 0;					// 表示进位
	int sum = 0;
	int index = 0;					// 表示result的下标,从0开始,相加结束后应翻转
	int i, j;

	i = 0;							// 表示str1的下标
	j = 0;							// 表示str2的下标

	while (i < len1 && j < len2)	// 两个数对应的每一位进行相加
	{
		sum = str1[i] - '0' + str2[j] - '0' + weight;
		weight = sum / 10;			// 计算是否要进位
		sum %= 10;			
		result[index++] = sum + '0';
		i++; 
		j++;
	}

	while (i < len1)				// str2已经加完了,这时还要考虑str1和str2的最高位相加时是否有进位的情况
	{
		sum = str1[i] - '0' + weight;
		weight = sum / 10;
		sum %= 10;
		result[index++] = sum + '0';
		i++; 		
	}

	while (j < len2)				// str1已经加完了,这时还要考虑str1和str2的最高位相加时是否有进位的情况
	{
		sum = str2[j] - '0' + weight;
		weight = sum / 10;
		sum %= 10;
		result[index++] = sum + '0';
		j++; 		
	}

	if (weight > 0)					// str1和str2都已经加完了,这时还要考虑最后一步中是否产生了进位
	{
		result[index++] = weight + '0';		
	}

	result[index] = '\0';
									
	Reverse(result, index);			// 对result进行翻转,得到最终的结果
}
2.大数相减

/*
** 这里假设str1和str2表示的数为非负数,并且str1表示的数大于等于str2的数
*/
void BigNumMinus(char *str1, char *str2, char *result)
{
	if (str1 == NULL || str2 == NULL || result == NULL)
	{
		return;
	}
	int len1, len2;

	len1 = strlen(str1);
	len2 = strlen(str2);

	Reverse(str1, len1);			// 将str1翻转
	Reverse(str2, len2);			// 将str2翻转

	int index = 0;					// 表示result的下标,从0开始,相减结束后应翻转
	int i, j;

	i = 0;							// 表示str1的下标
	j = 0;							// 表示str2的下标

	while (i < len1 && j < len2)	// 两个数对应的每一位进行相减
	{
		result[index] = (str1[i] - '0') - (str2[j] - '0');

		if (result[index] < 0)		// 当str1对应的位小于str2对应的位,应借位
		{
			result[index] = result[index] + 10 + '0';
			str1[i+1] = str1[i+1] - 1;
		}
		else
		{
			result[index] = result[index] + '0';
		}
		index++;
		i++; 
		j++;
	}
	
	while (i < len1)				// str2已减完,但是可能存在借位的情况
	{
		result[index] = str1[i] - '0';

		if (result[index] < 0)
		{
			result[index] = result[index] + 10 + '0';
			str1[i+1] = str1[i+1] - 1;
		}
		else
		{
			result[index] = result[index] + '0';
		}
		index++;
		i++; 		
	}
	
	while (result[--index] == '0')	// 去掉result后面的'0' 如40000 - 39999时会存在一些多源的'0'字符
		;

	result[++index] = '\0';

	Reverse(result, index);			// 对result进行翻转,得到最终的结果
}

3.大数相乘

/*
** 这里假设str1和str2表示的数为非负数,并且str1表示的数大于等于str2的数
*/
void BigNumMulti(char *str1, char *str2, char *result)
{
	if (str1 == NULL || str2 == NULL || result == NULL)
	{
		return;
	}

	if (strcmp(str1, "0") == 0 || strcmp(str2, "0") == 0)
	{
		strcpy(result, "0");
		return;
	}

	int len1, len2;

	len1 = strlen(str1);
	len2 = strlen(str2);

	Reverse(str1, len1);			// 将str1翻转
	Reverse(str2, len2);			// 将str2翻转

	memset(result, '0', N);

	int i, j;

	int multiFlag;					// 乘积进位
	int addFlag;					// 加法进位

	for (i = 0; i < len2; i++)		// str2的每一位
	{
		multiFlag = 0;
		addFlag = 0;
		for (j = 0; j < len1; j++) // str1的每一位
		{			
			int temp1 = (str2[i] - '0') * (str1[j] - '0') + multiFlag;
			multiFlag = temp1 / 10;
			temp1 = temp1 % 10;
			int temp2 = (result[i+j] - '0') + temp1 + addFlag;
			addFlag = temp2 / 10;
			result[i+j] = temp2 % 10 + '0'; 
		}
		result[i + len1] += multiFlag + addFlag;
	}

	if (result[len1+len2-1] == '0')
	{
		result[len1+len2-1] = '\0';
	}
	else
	{
		result[len1+len2] = '\0';
	}
	
	Reverse(result, strlen(result));	// 对result进行翻转,得到最终的结果
}





你可能感兴趣的:(C语言,数据结构和算法,C语言,大数相加,大数相减,大数相乘)