本文主要是写了笔者对于两种常用的大数相乘的代码的看法,主要作为备忘比较用,也在这里与大家分享!详细看代码
这是模拟正常计算
#include "iostream"
#include "cstdio"
using namespace std;
void reverseorder(char* str,int p,int q)//将数组逆序
{
char temp;
while(p<q)
{
temp=str[p];
str[p]=str[q];
str[q]=temp;
p++;
q--;
}
}
char* cal(char* str1,char* str2)//计算两个大数的乘积
{
int len1=strlen(str1);
int len2=strlen(str2);
char* result = new char[len1+len2+1];//多开一位,用来放'\0'
memset(result, '0',len1+len2);
result[len1+len2] = '\0';//在最后加上'\0',避免输出乱码
reverseorder(str1,0,len1-1);
reverseorder(str2,0,len2-1);
int i,j,add1,add2,t1,t2,l1,l2;
for(i=0;i<len1;i++)
{
add1=0;//乘积的进位
add2=0;//相加的进位
for(j=0;j<len2;j++)
{
t1=(str1[i]-'0')*(str2[j]-'0')+add1;//对应的两位数相乘
add1=t1/10;//取进位
l1=t1%10;//取个位
t2=result[i+j]-'0'+add2+l1;//用原本的值加上上一位进位的值,再加上当前为相乘的个位
add2=t2/10;//取进位给下次做加法
result[i+j]=t2%10+'0';//个位就是当前result的值
}
result[i+j]+=add1+add2;//当做到最后一次加法结束时,可能会产生进位,赋给进的下一位
}
reverseorder(result,0,len1+len2-1);//再将result逆序
return result;
}
int main()
{
char a[1000],b[1000];
scanf("%s%s",a,b);
char *result=cal(a,b);
if(result[0]!='0')//判断有没有进位
printf("%c",result[0]);
printf("%s",result+1);
delete [] result;
return 0;
}
非正常计算
/*对比另外一种大数乘法,这种方法代码简短很多,而且思路清晰,逻辑简单*/
#include "iostream"
#include "cstdio"
#include "string"
using namespace std;
string cal(string str1,string str2)
{
string str="";//结果
int i,j;
int len1=str1.length();
int len2=str2.length();
int result[1000]={0};//先定义一个int型的结果,方便计算
for(i=0;i<len1;i++)
for(j=0;j<len2;j++)
{
result[len1-i-1+len2-j-1]+=(str1[i]-'0')*(str2[j]-'0');//将对应位运算结果先放入result中,不处理,最大值为89
}
for(i=0;i<len1+len2;i++)
{
result[i+1]+=result[i]/10;//进位
result[i]=result[i]%10;//取各位
}
for(i=len1+len2-1;i>=0;i--)
{
if(result[i]!=0) break;//查找首位不为0的位置
}
for(j=i;j>=0;j--)//从不为0的位置开始将结果放在str中并加上'0'
{
str+=result[j]+'0';
}
return str;
}
int main()
{
string str1,str2;
cin>>str1>>str2;
cout<<cal(str1,str2)<<endl;
return 0;
}