C语言大数运算——减法

接着加法之后写了个减法,大数减法主要有几个问题
1.减完了后是负数怎么办?
2.减完了后有几位数?
3.减法的操作是如何进行的?

/**************************************************************************************/ 
/*						大数运算篇——减法   										      */ 
/*  123456          分析:从最低位到最高位,先判断再相减 6小于7 6+10-7=9 5-1=4             */ 
/*       -                小于的情况下加10再减,高一位的数字要减掉1                    	  */ 
/*     937                大于的情况下直接减去                                        	  */ 
/* =123330          	  被减数多于的数并不是直接写入结果           			          */
/**************************************************************************************/
/*具体问题:
	1.两数相减,减数比被减数大怎么办?   一开始先判断,把大的数给被减数,之后添负号 
  	2.最后的结果位数怎么确定?           前面为0的数全部删掉
	3.减法具体实现                       见分析
	4.需要注意负数添负号时候移动的位置数,前有3个0,但是只向前移动2位,第一位放置负号
	5.在相减的时候,需要注意的是:当减数已经全部减掉以后,被减数剩余部分并不是直接下,
	  需要根据 <0 则加10然后前一位减一来进行
	6.两个数据的比较,位数相等的时候用遍历逐个比较直到找出最大的否者结果为0 
*/
//作者:fat pears 最近更新时间:2019.01.30 
/*代码实现*/


#include<stdio.h>
#include<string.h>
#define N 10000


int main()
{
	char date_1[N]={0},date_2[N]={0};                 //用来保存输入数据 
	char num_1[N]={0},num_2[N]={0},result[N]={0};     //用来运算的数组 
	long len_1,len_2,len;                             //k最后与是否添负号有关 
	int i,t,k=1; 
	 
	printf("请输入第一个数\n");
	scanf("%s",date_1);
	getchar();
	printf("请输入第二个数\n"); 
	gets(date_2);
	
	//计算两个数的位数,把较大的数给num_1  
	len_1 = strlen(date_1);
	len_2 = strlen(date_2);
	len   = len_1>len_2? len_1:len_2;
	if(len_1>len_2)
	{
		strcpy(num_1,date_1);
		strcpy(num_2,date_2);	
	}
	else if(len_1 == len_2)
	{
		for(i = 0;i<len_1;i++)
		{
			if(date_1[i]!=date_2[i])
			{
				if(date_1[i]>date_2[i])
				{
					strcpy(num_1,date_1);
					strcpy(num_2,date_2);
				}
				else
				{
					strcpy(num_2,date_1);
					strcpy(num_1,date_2);
					k = 0;
				}
				goto jianfa;	
			}	
		}
		result[0] = '0';
		goto end;	
	}
	else
	{
		strcpy(num_2,date_1);
		strcpy(num_1,date_2);
		k = 0;
	}    
	
	jianfa:
	len_1 = strlen(num_1);       //重新更新len_1,len_2所代表的长度 
	len_2 = strlen(num_2);
	
	//倒序相减直到小的数被减完为止 
	for(i = 0;i<len_1&&i<len_2;i++)
	{
		if(num_1[len_1-1-i]<num_2[len_2-1-i])
		{
			num_1[len_1-1-i] += 10;
			num_1[len_1-1-i-1]--;
		}
		result[len-1-i] = num_1[len_1-1-i] - num_2[len_2-1-i] + '0';    //需要注意,这里减完的结果并不是ASC2码,而是数值的0-9,应该加上'0' 
	}
	
	//num_1中剩余的数比0小的也要变9,上一位减1 
	for(;i<len;i++)
	{
		if(num_1[len_1-1-i]<'0')
		{
			num_1[len_1-1-i] += 10;
			num_1[len_1-1-i-1]--;
		}
		result[len-1-i] = num_1[len_1-1-i];
		
		
	}

	 
	 //判断是否是负数以及删除全部前导0并变回数字的ASC2码 
	 if(k == 1)
	 {
	 	for(i = 0;i<len;i++)
	 	{
	 		if(result[i]!='0')
	 		{
	 			t = i;
	 			break;
		 	}
	 	}
	 	for(;i<len;i++)
	 	{
	 		result[i-t] = result[i];
	 	}
	 	result[len-t] = '\0';	
	} 
	else
	{
		for(i = 0;i<len;i++)
	 	{
	 		if(result[i]!='0')
	 		{
	 			t = i;
	 			break;
		 	}
	 	}
	 	if(t>0)   //前移位数超过0位 
	 	{
	 		for(;i<len;i++)
	 		{
	 			result[i-t+1] = result[i];
	 		}
	 		result[len-t+1] = '\0';
	 		result[0] = '-';
		 }
		 else     //为了放置负号要往后移一位 
		 {
		 	for(i = len-1;i>=0;i--)
	 		{
	 			result[i+1] = result[i];
	 		}
	 		result[len+1] = '\0';
	 		result[0] = '-';
		 }
	 	
	} 	
	
	end:	
    printf("两个数相减的结果是:\n");
    puts(result);
      
    return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值