当两个比较大的整数相乘时,可能会出现数据溢出的情形。为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法。具体来说,首先以字符串的形式输入两个整数,每个整数的长度不会超过8位,然后把它们相乘的结果存储在另一个字符串当中(长度不会超过16位),最后把这个字符串打印出来。例如,假设用户输入为:62773417和12345678,则输出结果为:774980393241726.
输入:
62773417 12345678
输出:
输入:
62773417 12345678
输出:
774980393241726
本题思路就是模拟手算过程。
#include<stdio.h> /*try_fei_ge*/
#include<math.h>
#include<string.h>
void up(char c[],int cur); /*进位*/
int main()
{
int i,j,k,l,j_wei,j_cur,i_wei,number;
char ch='+',a[16],b[16],c[100000];
memset(c,0,sizeof(c));
scanf("%s %s",a,b);
i=strlen(a)-1;
j=strlen(b)-1;
if(a[0]=='-') /*判断数a是否为负数若是记录下负号并且将其余元素前移*/
{
ch='-';
for(k=0;k<=i;k++)
a[k]=a[k+1];
}
if(b[0]=='-')
{
if(ch=='-') ch='+';
else ch='-';
for(k=0;k<=j;k++)
b[k]=b[k+1];
}
for(k=0;k<=i;k++) /*将字符一转化为ascll码表示,避免计算时超过127*/
a[k]=a[k]-'0';
for(l=0;l<=j;l++)
b[l]=b[l]-'0';
for(i_wei=0;i>=0;i--,i_wei++) /*从数a最低位开始运算*/
{
for(j_wei=0,j_cur=j;j_cur>=0;j_cur--,j_wei++) /*使数b每一位与数a相乘并将结果相加*/
{
number=a[i]*b[j_cur]; /*将两数相乘结果暂时放置一位中*/
c[i_wei+j_wei]=c[i_wei+j_wei]+number;/*注意此处下标与当前数是十的几倍有关!*/
up(c,i_wei+j_wei); /*判断该位是否大于10需要进位*/
}
}
for(i=99999;c[i]==0&&i>=0;i--) ;/*运算时逆序保存,找到最高位*/
if(ch=='-') printf("-"); /*如果为负数输出负号*/
if(i==-1) putchar('0'); /*如果遍历到数组0处任未找到数则为0*/
else for(;i>=0;i--) /*输出数*/
printf("%c",c[i]+'0');/*开始时ascll码缩小至0~9,现在扩大回去*/
return 0;
}
void up(char c[],int cur)
{
int ch;
if((ch=c[cur])>=10)/*当前位小于0不在进位*/
{
c[cur]=(ch%10);
c[cur+1]=c[cur+1]+(ch/10);
up(c,cur+1); /*递归判断当前进位后下一位是否需要进位*/
}
}
version 2.0
#include<stdio.h> /*try_fei_ge*/
#include<string.h>
void carry(char c[],int cur);
int main(
{
int la,lb;
int start = 399,offest = 0;
char a[200],b[200],c[400];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
scanf("%s",a);
scanf("%s",b);
la = strlen(a);
lb = strlen(b);
--la;--lb;
if(la == 0 && a[la] == '0') {printf("0");return 0;}
if(lb == 0 && b[lb] == '0') {printf("0");return 0;}
for(int cur_a = la;cur_a >= 0;cur_a--)
for(int cur_b = lb;cur_b >= 0;cur_b--)
{
int cur = start - (lb - cur_b) - (la - cur_a);
c[cur] += (b[cur_b] - '0') * (a[cur_a] - '0');
carry(c,cur);
}
int i = 0;
for(;i <= start;i++)
if(c[i] != 0)
break;
for(;i <= start;i++)
printf("%d",c[i]);
return 0;
}
void carry(char c[],int cur)
{
if(c[cur] >= 10)
{
c[cur-1] += c[cur] / 10;
c[cur] = c[cur] % 10;
carry(c,cur-1);
}
}