关于大整数的加减法

大整数

我们在学习C语言时会遇到这样一个问题:当整型数据类型无法存储时,会自然想到长整型数据类型,其数据范围为-2147483647 到 2147483647。而当数据在大一点呢?我们称这样的整数叫做大整数,以此便产生了一系列的关于大整数的算法。

大整数的加减

在阅读了网上那么多的关于大整数的计算后,发现方法不尽相同,但大多都只限于特殊的算法,比如仅适用正整数相加减,但我们知道大整数的加减除上述之外,还有负数的相加减,异号大整数的相加减,那么如何在一个程序中实现呢?作者根据自己所学(作者也是新手…)与思考,完成以下程序:

#include<stdio.h>
#include<string.h>
#define MAX 400//最大运算位 
void BIGPLUS(int *num1,int *num2,int length1,int length2);//大整数相加函数 
void BIGMINUS(int *num1,int *num2,int length1,int length2);//大整数相减函数 
void  BIGDEAL(char *a1,int *num); //大整数有字符型向整形转换 
void  BIGDEAL(char *a1,int *num)
{ int i,j,length;
 length=strlen(a1);
 if(a1[0]==45)//判断首位如果是“-”号,则num[0]记作1;否则记作0; 
   { num[0]=1;
    for(i=1;i<=length-1;i++)//因为长度中包含一个符号位,所以运算时实际长度减一,从下标1开始 
 {j=i;
 num[j]=a1[i]-48;//将字符数字转化成实际整型数字 
 }} 
 else 
 {
 num[0]=0;
    for(i=0;i<length;i++)
 {j=i+1;
 num[j]=a1[i]-48;
}}}

void BIGPLUS(int *num1,int *num2,int length1,int length2)//大整数加法 
{
int num3[MAX];
int i,j,k,kaiguan;
if(num1[0]==num2[0])//符号相同时的加法 
{
if(num1[0]==1)//若都为负数 
{
i=length1-1;//指示下标应为长度减一,因为有符号算作长度 
j=length2-1;
k=1;num3[k]=0;
while(i>0&&j>0)//进行相加进位 
{
 num3[k]=num1[i]+num2[j]+num3[k];
 num3[k+1]=num3[k]/10;
 num3[k]=num3[k]%10;
 i--;j--;k++;
}
if(i>0)//判断哪一个大整数还有剩余 
{
for(;i>0;i--)
{
	num3[k]=num1[i]+num3[k];//同样进行累加进位 
	num3[k+1]=num3[k]/10;
	num3[k]=num3[k]%10;
	k++;}}
else
{if(j>0)
{
	for(;j>0;j--)
	{
	num3[k]=num2[j]+num3[k];
	num3[k+1]=num3[k]/10;
	num3[k]=num3[k]%10;
	k++;
	}}}
if(i==0&&j==0)
{
printf("-");
if(num3[k]==0)
k--;
for(;k>=1;k--)
printf("%d",num3[k]);
}}
else//当全为正数时,下标长度和实际长度一致 
{
	i=length1;//算法过程和负数相似,主要是在长度上少了符号位
j=length2;
k=1;num3[k]=0;
while(i>0&&j>0)
{
 num3[k]=num1[i]+num2[j]+num3[k];
 num3[k+1]=num3[k]/10;
 num3[k]=num3[k]%10;
 i--;j--;k++;
}
if(i>0)
{
for(;i>0;i--)
{
	num3[k]=num1[i]+num3[k];
	num3[k+1]=num3[k]/10;
	num3[k]=num3[k]%10;
	k++;
}}
else
{if(j>0)
{
	for(;j>0;j--)
	{
	num3[k]=num2[j]+num3[k];
	num3[k+1]=num3[k]/10;
	num3[k]=num3[k]%10;
	k++;
	}}}
if(i==0&&j==0)
{
if(num3[k]==0)
k--;
for(;k>=1;k--)
printf("%d",num3[k]);
}}
printf("按下任意数字键继续:\n");
scanf("%d",&kaiguan);}
else//符号不同 ,判断负数位置进行减法运算,可以将负的大整数处理成正整数调用减法函数 
{
	if(num2[0]==1)
	{
       num2[0]=0;
BIGMINUS(num1,num2,length1,length2-1);
}
else
{
num1[0]=0;
BIGMINUS(num2,num1,length2,length1-1);
}} 
}

void BIGMINUS(int *num1,int *num2,int length1,int length2)//减法函数
{int i,j,k,key,kaiguan;
int d[MAX];
	if(num1[0]==num2[0])//判断两大整数符号位是否相同
	{
	if(num1[0]==0)//如果两个减数都为正数 
	{
	key=1;//用key的值标记被减数与减数之间的大小关系
	i=length1;
	j=length2;
	if(length1>length2)//首先比较长度
	    key=1;
	    else
		{
		if(length1==length2)//若长度相同比较位次上数的大小
	    {for(i=1;i<=length1;i++)
	    {if(num1[i]>num2[i])
	    {key=1;
	    break;}
		else
	    {if(num1[i]<num2[i])
	    {key=0;break;}}
		}
		}
		else
		{
		if(length1<length2)//若被减数长度小于减数时
		key=0;}
	    }
	    i=length1;
	j=length2;
	   
	    if(key==1)//如果第一个数比第二个数大 
	    
	    { k=0;d[k]==0;
		
		while(i>0&&j>0)//进行相减运算
	    {if(num1[i]<num2[j])
	    {num1[i]=num1[i]+10;
	    num1[i-1]=num1[i-1]-1;
		}
		d[k]=num1[i]-num2[j];
		k++;
		d[k]=0;
		i--;j--;
		}
		if(i>0)
		for(;i>0;i--)
		{d[k]=num1[i];
		k++;
		d[k]=0;
		}
		for(;k>0;k--)
		{if(d[k]!=0)
		break;
		}
		for(;k>=0;k--)
		printf("%d",d[k]);
	printf("按下任意数字键继续:\n");
scanf("%d",&kaiguan);
		}
		else
		{if(key==0)
		{printf("-");
		BIGMINUS(num2,num1,length2,length1);
		}}
		
		}else
		if(num1[0]==1)//如果两个都是负数,负负得正交换位置再相减
		{
		num1[0]=0;num2[0]=0;
		BIGMINUS(num2,num1,length2-1,length1-1);}
		 }
		 else
		 {
		 if(num1[0]==0&&num2[0]==1)//若正减负,则可以处理成两数绝对值相加,调用加法函数
		{
		num2[0]=0;
		  BIGPLUS(num1,num2,length1,length2-1);}
		  else
		  {
		  if(num1[0]==1&&num2[0]==0)//若负减正,提取符号绝对值相加,调用加法函数
		  {num1[0]=0;
		  printf("-");
		  BIGPLUS(num1,num2,length1-1,length2);}
		  
		  }	} }



main()//主函数 
{
char s1[MAX],s2[MAX];//建立两个字符串存放大整数 
char zhizheng;
int num1[MAX],num2[MAX]; //建立两个数组用来存放大整数 
int length1,length2,i;
printf("请输入要操作两个大整数:\n");
gets(s1);
gets(s2);
printf("输入运算符,仅支持+、-、*\n");
zhizheng=getchar();
length1=strlen(s1);
length2=strlen(s2);
 BIGDEAL(s1,num1);
 BIGDEAL(s2,num2);
switch(zhizheng)
 {
 	case '+':
 		BIGPLUS(num1,num2,length1,length2);break;
 	case '-':
 			BIGMINUS(num1,num2,length1,length2);break;

 };

}

如有不对之处,请多指教

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值