回复 7楼 lin5161678
估计你是说通过“c[l]=(i?a[--i]:'0')+(j?b[--j]:'0')+k-'0';
//做加法:A+b+进位”的方式减少两行代码。实际上这是不规范的,可能产生系列点问题,在不同编译器上得到不同结果。
看到楼主又发了大数乘法,忍不住也写了个,现在把大数加法和乘法都变成函数调用的方式了,代码如下:
程序代码:
#include <stdio.h>
int largadd(char *,char *,char *,int);
int largmult(char *,char *,char *,int);
void main()
{
char a[1001],b[1001],c[2002];
while(scanf("%s%s",a,b))
{
printf("%s\n",c+largadd(a,b,c,2002));
printf("%s\n",c+largmult(a,b,c,2002));
}
}
int largadd(char *a,char *b,char *c,int len)
{//大数加法,a:被加数 b:加数 c:相加结果 len:数组c的长度
int i,j,k,l=len-1;
for(i=0;a[i];i++);
for(j=0;b[j];j++); //把指针调整到加数、被加数最后一位,从个位数开始加
for(k=c[l]=0,l--;i||j||k;l--) //把相加结果从c[l-2]--c[0]存储
{
c[l]=(i?a[i-1]:'0')+(j?b[j-1]:'0')+k-'0'; //做加法:A+b+进位
k=0;
if(c[l]>'9')
{
k=1;
c[l]-=10; //处理进位
}
if(i)i--;
if(j)j--;
}
//可在这里加消前导0的代码,否则000009+1=000010
return l+1;
}
int largmult(char *a,char *b,char *c,int len)
{//大数乘法,a:被乘数 b:乘数 c:相乘结果 len:数组c的长度
int i,j,k,l,m,n;
for(m=0;a[m];m++);
for(n=0;b[n];n++); //把指针调整到乘数、被乘数最后一位,从个位数开始相乘
for(i=0;i<len;i++)c[i]=0; //运算结果先清零
for(i=n;i;i--)
{
l=len+i-n-2;
for(k=0,j=m;j;j--)
{//按位做乘法
c[l]=(a[j-1]-'0')*(b[i-1]-'0')+k+c[l];
k=c[l]/10;
c[l]=c[l]%10;
l--;
}
c[l]+=k; //按位乘法补进位
}
if(k)c[l--]=k; //最终结果补进位
for(i=l+1;i<len-1;i++)
{
c[i]+='0';
if(c[i]=='0')l++; //调整数字为字符串同时消前导0
}
if(!c[l+1])l--; //如果字符串长度为0,至少显示一个0,如999999999999*0结果不会消所有前导0
return l+1;
}