大整数
我们在学习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;
};
}
如有不对之处,请多指教