题目描述
特大整数用长整型也存不下,如果用双精度实型存储则会造成误差,可以用字符数组存储所有位,再按十进制由低到高逐位相加,同时考虑进位。
特别提示:假设特大整数不超过30位。参与操作的数据中,被减数>减数。
算法分析:
1.初始化:将两个特大整数输入两个字符数组,将两个字符数组的各元素右移,使最低位的元素位置对齐,高位补0,为了存储最高位的进位,位数多的数最高位前也应补一个0。
2.从最低位对应的数组元素开始将数字字符转换为整型数据相加,因为数字字符‘0’对应的ASCII值是48,则:整型数据1+2,相当于 ('1'-48)+('2'-48),即'1'+'2'-96。
3.将和整除以10,余数就是该位的结果,并转换为字符(整型数据+48)存入该位,商就是进位数。
4.再对高一位对应的数组元素操作,将该位数字字符转换为整型相加,并与低位的进位数相加,将和整除以10,余数就是该位的结果,商就是本位的进位数。
5.重复4直到最高位。如果最高位相加时进位数大于0则将此进位数转换为字符存入最高位。
输入
第一行待运算的表达式个数n,之后连续的2n行每相邻得两行为一组。
输出
依次输出运算结果,共输出2n行。前n行为相加的运算结果;后n行为相减的运算结果,每个结果独占一行。
样例输入
3 123456789 23456789 999999999 999999999 1000000000 9999
样例输出
146913578 1999999998 1000009999 100000000 0 999990001
#include<stdio.h>
#include<string.h>
void reverse(char *str);//倒置
void addbig(char *str1,char *str2,char *result);//大整数加法
void redubig(char *str1,char *str2,char *result);//大整数减法
int main()
{
int n;
char str1[100]={0},str2[100]={0};
char result[100]={0};
char reduce[100]={0};
char begin[100][100]={0};
char end[100][100]={0};
int k,j;
int total;
scanf("%d",&n);
total=n;
getchar();
k=0;
while(n--&&k<total)
{
gets(str1);
gets(str2);
reverse(str1);
reverse(str2);
addbig(str1,str2,result);
strcpy(begin[k],result);
redubig(str1,str2,reduce);
strcpy(end[k++],reduce);
}
for(k=0;k<total;k++)
printf("%s\n",begin[k]);
for(k=0;k<total;k++) {
int buf = 0, szsz = strlen(end[k]);//计数有几个零
while (end[k][buf] == '0' && buf != szsz - 1)//保留最后一个0
buf++;
printf("%s\n",end[k]+buf);然后在首部加上计数的零,就可以输出高位没有0的结果
}
}
void reverse(char *str)
{
char tmp;
int len,i;
len=strlen(str);//有效防止'\0'被记入
for(i=0;i<len/2;i++)
{
tmp=str[i];
str[i]=str[len-i-1];
str[len-i-1]=tmp;
}
}
void addbig(char *str1,char *str2,char *result)
{
int len1,len2;
int jin=0;
int i;
int tmp;
len1=strlen(str1);
len2=strlen(str2);
for(i=0;i<len1&&i<len2;i++)
{
tmp=str1[i]-'0'+str2[i]-'0'+jin;
result[i]=tmp%10+'0';
if(tmp>=10)//大于10,进位
jin=1;
else
jin=0;
}
if(i<len1)//如果字符串1长
{
for(;i<len1;i++)
{
tmp=str1[i]-'0'+jin;
result[i]=tmp%10+'0';//多余进位
if(tmp>=10)
jin=1;
else
jin=0;
}
}
if(i<len2)//如果字符串2长
{
for(;i<len2;i++)
{
tmp=str2[i]-'0'+jin;
result[i]=tmp%10+jin;
if(tmp>=10)
jin=1;
else
jin=0;
}
}
if(jin)
result[i++]='1';//防止最后一个数进位,199+900
result[i]='\0';
reverse(result);
}
void redubig(char *str1,char *str2,char *reduce)
{
int len1,len2;
int jin=0;
int i;
len1=strlen(str1);
len2=strlen(str2);
for(i=0;i<len1&&i<len2;i++)
{
if(str1[i]<str2[i])
{
reduce[i]=(str1[i]-str2[i]+10+jin)+'0';//注意,字符数字减法就是数字减法
jin=-1;
}
else
{
reduce[i]=(str1[i]-str2[i]+jin)+'0';
jin=0;
}
}
if(i<len1)//字符串1长
{
for(;i<len1;i++)
{
if(str1[i]=='0'&&jin==-1)
{
reduce[i]=(str1[i]-'0'+10+jin)+'0';
jin=-1;
}
else if(str1[i]!='0'&&jin==-1)
{
reduce[i]=(str1[i]-'0'+jin)+'0';
jin=0;
}
else if(str1[i]!='0'&&jin==0)
reduce[i]=str1[i];
}
}
if(i<len2)//字符串2长
{
for(;i<len2;i++)
{
if(str2[i]=='0'&&jin==-1)
{
reduce[i]=(str2[i]-'0'+10+jin)+'0';
}
else if(str2[i]!='0'&&jin==-1)
{
reduce[i]=(str2[i]-'0'+jin)+'0';
jin=0;
}
else if(str2[i]!='0'&&jin==0)
reduce[i]=str2[i];
}
}
if(reduce[i]=='0')
reduce[i]='\0';
reverse(reduce);
}