在标准C++中,int类型可表示数的范围是-2^31~2^31-1。而在实际运算中,可能用到的数可能会远远超出int或long类型的范围。而此时如果继续用int或long的话必然会出现错误。此时就需要我们用到“大数”这个概念。通过string和vector为载体来进行运算,因为字符串或容器没有长度的限制。具体代码如下:
using namespace std;
#include<iostream>
#include<string>
#include<vector>
void function()
{
int i,j,k;
int numlen1,numlen2,tmpdata;
vector<int>num1,num2,num3;
string numtmp1,numtmp2;
cout<<"Please Enter num1:"; /*将需要相乘的两个数输入到字符串中*/
cin>>numtmp1;
cout<<"Please Enter num2:";
cin>>numtmp2;
numlen1=numtmp1.length(); /*分别得到两个字符串的长度,即两个数的位数*/
numlen2=numtmp2.length();
for(i=0;i<numlen1;i++)
{
num1.push_back(numtmp1[i]-'0'); /*将每一位的字符转化为数字存储到容器中*/
}
for(j=0;j<numlen2;j++)
{
num2.push_back(numtmp2[j]-'0');
}
for(i=numlen1-1;i>=0;i--) /*num2的最低位依次与num1的每一位相乘,不考虑进位*/
{ /*最低位不与其他位放在一起运算,后面小结会有说明*/
j=numlen2-1;
tmpdata=num1[i]*num2[j];
num3.push_back(tmpdata); /*将运算得到的数按位存储到新的容器num3中*/
}
for(j=numlen2-2;j>=0;j--) /*从num2的倒数第二位开始再与num1的每一位相乘*/
{
k=numlen2-1-j; /*用k来限制得到的结果存储在第几位*/
num3.push_back(0); /*每次运算都要在容器后新加一个元素作为进位*/
for(i=numlen1-1;i>=0;i--)
{
num3[k]=num1[i]*num2[j]+num3[k]; /*相乘后加上当前位原有的值即为当前位的值*/
k++;
}
}
for(k=0;k<num3.size();k++) /*所有位都运算完成后统一进位*/
{
if(num3[k]>=10)
{
tmpdata=num3[k]/10;
num3[k+1]+=tmpdata;
num3[k]=num3[k]%10;
}
}
cout<<"-------After Calculating--------"<<endl;
cout<<"num1*num2=";
for(i=num3.size()-1;i>=0;i--) /*在num3中存的数是倒叙排列,需要反着输出*/
{
cout<<num3[i];
}
}
int main()
{
function();
return 0;
}
运行结果:
小结:
类似于小学乘法中列的竖式。将num1写在上面,num2写在下面。从num2的最后一位开始,每一位依次与num1的每一位相乘。上面的代码中,并没有将最低位与其他位一起运算。其原因是,每一次运算需要加这个位上原有的值,才可以得到当前位的值。而第一次运算容器是空的,没有初始的值,所以无法与其他位放在一起。第一次运算过后,每一位上都有了值,便可以加了。在竖式中我们都知道,每一次相乘都要向左移一位,意为乘10。而这里也需要考虑到这个问题。而每次向左移一位都会出现新的进位,所以每次都需要在容器尾新加一个元素,并赋初值为0,与新进的位相加。由于num3中存储的数是倒着排的,在显示的时候需要我们逆序输出。