大整数
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;
};
}
何か問題がある場合は、アドバイスしてください