c/c++中int和unsigned类型变量,都不能保存超过10位的整数,但有时我们需要计算位数非常长的整数或小数的加法。一般我们称这种基本数据类型无法表示的整数为大整数。如何表示和存放大整数呢?基本的思想就是:用数组存放和表示大整数。一个数组元素,存放大整数中的一位。
现在假如我们要计算俩个200位数的加法。显然,任何C/C++固有类型的变量都无法保存它。最直观的想法是可以用一个字符串来保存它。字符串本质上就是一个字符数组,因此为了编程更方便,我们也可以用数组int an[200]来保存一个200 位的整数,让an[0]存放个位数,an[1]存放十位数,an[2]存放百位数……那么如何实现两个大整数相加呢?方法很简单,就是模拟小学生列竖式做加法,从个位开始逐位相加,超过或达到10 则进位。也就是说,用int an1[201]保存第一个数,用int an2[200]表示第二个数,然后逐位相加,相加的结果直接存放在an1 中。要注意处理进位。另外,an1 数组长度定为201,是因为两个200 位整数相加,结果可能会有201 位。实际编程时,不一定要费心思去把数组大小定得正好合适,稍微开大点也无所谓,以免不小心没有算准这个“正好合适”的数值,而导致数组小了,产生越界错误。
下面是具体程序:
#include<stdio.h>#include<string.h>
#defineMAX_LEN 200
int an1[MAX_LEN+10]
int an2[MAX_LEN+10]
charszLine1[MAX_LEN+10]
charszLine2[MAX_LEN+10]
int main(void)
{
scanf("%s", szLine1)
scanf("%s", szLine2)
inti, j
memset( an1, 0, sizeof(an1))
memset( an2, 0, sizeof(an2))
int nLen1 = strlen( szLine1)
for( j = 0, i = nLen1 - 1i >= 0 i--)
an1[j++] = szLine1[i]- '0'
int nLen2 = strlen(szLine2)
for( j = 0, i = nLen2 - 1i >= 0 i--)
an2[j++] = szLine2[i]- '0'
for( i = 0i < MAX_LEN i++ )
{ an1[i]+= an2[i]//逐位相加
if( an1[i] >= 10 )
{ //看是否要进位
an1[i] -= 10
an1[i+1] ++ //进位
}
}
for( i = MAX_LEN (i>= 0) && (an1[i] == 0) i-- )
if(i>=0)
for( i >= 0 i--)
printf("%d", an1[i])
else printf("0")
return 0
}
d串末尾缺了个字符串结尾符'\0'需要补上。
d[l+1] ='\0'至于d输出时开头的零,这是面对多位数可能进位也可能不进位之类问题造成的多位数的位数不定的困惑,无奈之举。有个办法就是扫描处理进位问题的动作是可以提前先在倒装着的c串上完成了的,这样d串的长度就确定再将c串倒装搬到c串。
PS:LZ使用scanf返回值的方法有问题,scanf返回值是指成功获得输入的参数个数,应该直接用
while(scanf("%s%s",&a,&b)==2)比较妥当。
LZ错误不少啊#include <stdio.h>
#include <string.h>
int main()
{
char a[1000],b[1000],e[2001]
int i,p,q,k
int c[1000]={0},d[1000]={0},sum[1001]={0}
int len_a,len_b
scanf("%s",e)
p=strlen(e)
for(i=0i<p i++)
{
if(e[i]==',')
{
break
}
a[i]=e[i]
}
len_a=i-1
i++
for(k=0i<pi++,k++)
b[k]=e[i]
len_b=k-1
for(i=0i<=len_ai++)
c[i]=a[len_a-i]-'0'
for(i=0i<=len_bi++)
d[i]=b[len_b-i]-'0'
for(i=0i<=len_a||i<=len_bi++)
{
sum[i]+=c[i]+d[i]
if(sum[i]>=10)
{
++sum[i+1]
sum[i]-=10
}
}
if(sum[i--]>0)printf("1")
for(i>=0i--)
printf("%d",sum[i])
return 0
}