高精度乘法的处理方法
1.问题的输入,由于是大整数,所以其范围一般超过了整型和实型所能表示的范围,故不能用整型或者实型来接受输入,故考虑字符串或者数组。
数组:a.优点:一位存储,可直接进行四则运算
b。缺点:输入不方便。
字符串:a.优点:输入方便
b。缺点:输入后要转换成相应的数字。
一般选择字符串来进行输入。
2.倒序问题:高精度乘法采用的是模拟笔算方法,在将字符串转换为对应的整型数组时需要将字符串倒序。
3.模拟笔算过程:
例:123*456的过程
1 2 3
* 4 5 6
6 12 18
5 10 15
4 8 12
4 13 28 27 18
进位可以在计算过程中处理, 也可以在计算结束后计算。
故模拟笔算算法的过程是:1.被乘数的每一位分别与乘数相加,再将每一列的结果相加,然后处理进位。最后把结果倒序即可。
下列代码实现被乘数每一位和乘数相乘,对应列相加:
for(i = 0; i < len_a; i++)
{
for(j=0; j < len_b; j++)
{
c[i+j] += a[i] * b[j];
}
}
处理进位:
for(int i = 0; i < LEN*2; i++)
{
if (10 <= c[i])
{
c[i + 1] += c[i]/10;
c[i] %= 10;
}
}
结果为: c[6]={8,8,0,6,5,0}
然后在进行一步倒序操作,就得到了高精度乘法下的最终结果。
下面是完整代码:
#include<iostream>
#include<string>
using namespace std;
const int LEN = 128;
int main()
{
string str1, str2;
int a[LEN], b[LEN], c[LEN*2];
int j;
memset(a, 0, LEN*sizeof(int));//初始化置零
memset(b, 0, LEN*sizeof(int));
memset(c, 0, 2*LEN*sizeof(int));
cin>>str1>>str2;//输入乘数和被乘数
j = 0;
for (int i = str1.size() - 1; i >= 0; i--)//倒置字符串str1并保存到数组里
{
a[j] = static_cast(str1[i] - '0');
++j;
}
j = 0;
for (int i = str2.size() -1; i >= 0;i-- )//倒置字符串str2并保存到数组里
{
b[j] = static_cast(str2[i] - '0');
++j;
}
for (int i = 0; i < str1.size(); i++)
{
for (j = 0; j < str2.size(); j++)
{
c[i+j] += a[i]*b[j];//对应位相乘
}
}
for(int i = 0; i < LEN*2; i++)
{
if (10 <= c[i])//判断是否需要进位
{
c[i + 1] += c[i]/10;//取十位数字,进位
c[i] %= 10;//取个位数字,保存到c[i]
}
}
for (j = LEN*2 - 1; j >= 0; j--)
{
if (0 != c[j])
{
break;
}
}
for (int i = j; i>=0; i--)
{
cout<<c[i];
}
return 0;
}