高精度乘法基本算法,两段,其实两段是同一种方法,第二段稍做优化。只是将计算结果显示到屏幕上。
所谓高精度乘法,是指计算超过标准数据类型能够表达的计算范围的乘法计算。
如果计算机结果已经超过long long所能表示的范围,将会得到溢出后的答案(结果不正确,也不能计算)
这时候就需要用到高精度乘法算法,所谓高精度乘法算法,无非也就是通过录入字符数组的形式保存数字为字符串,然后逐一取出录入的数字字符,转换成对应的int数字,然后利用计算机善于重复循环处理数据的特点,模拟乘法竖式的计算过程,通过进位和错位相加的形式,得到高精度计算结果。
代码片段一(初学请参考这段代码):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
//定义常量,常量值根据需要修改,此算法为完全根据乘法竖式模拟算法,没有优化
//并且浪费了a[0]、b[0]、c[0](因为这三个数组的第一个元素就没用到)
#define LENGTH 1001
int main(){
//准备,以字符串形式读入乘数
char a1[LENGTH],b1[LENGTH];
//准备,转换读入的乘数,逆序存放到数字数组
int a[LENGTH],b[LENGTH],c[LENGTH];
int lena,lenb,lenc,i,j,x;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
//读取乘数
gets(a1);
gets(b1);
lena = strlen(a1);
lenb = strlen(b1);
//把刚才读取进来的乘数,逆序转换成int类型数字保存到int数组里
for (i = 0;i < lena;i++){
a[lena - i] = a1[i] - 48;
//0的ASCII码是48,这里char类型和int类型是不一样的,需要减去差值转换成实际的int,这一局其实相当于
//a[lena - i] = a1[i] - '0';
}
for (i = 0;i < lenb; i++){
b[lenb - i] = b1[i] - 48;
}
for (i = 1; i <= lena; i++){
x = 0;//初始化进位
for (j = 1; j <= lenb; j++){
//模拟乘法竖式,进位、错位相加
c[i + j - 1] = a[i] * b[j] + x + c[i + j - 1];
x = c[i + j - 1] / 10;//乘法进位
c[i + j - 1] %= 10;//进位后保留个位
}
c[lenb + i] = x; //错位相加高位进位(先把进位加到高位)
}
lenc = lena + lenb;//两个非零因数相乘,积的位数要么是两个因数位数之和,要么是两个因数位数之和-1
//检查最高位是否为0,如果为0,退一位,while循环可以保证即使因数是0也能输出正确的结果而不输出多余前导0
while (c[lenc] == 0 && lenc > 1){
lenc--;
}
for (i = lenc; i >= 1; i--){
cout<<c[i];
}
return 0;
}
代码片段二(理解第一段代码的基础上,再看看自己能否将代码改成这样):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
//定义常量,常量值根据实际需要修改,此算法模拟乘法竖式计算过程
//代码做过一定优化,数组空间从下标0(第一个元素)开始使用
#define LENGTH 1000
int main(){
//准备,以字符串形式读入乘数
char a1[LENGTH],b1[LENGTH];
//准备,转换读入的乘数,逆序存放到数字数组
int a[LENGTH],b[LENGTH],c[LENGTH];
int lena,lenb,lenc,i,j,x;
//初始化数组
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
//读取乘数
gets(a1);
gets(b1);
lena = strlen(a1);
lenb = strlen(b1);
//把刚才读取进来的乘数,逆序转换成int类型数字保存到int数组里
for (i = 0;i < lena;i++){
a[lena - i - 1] = a1[i] - 48;
}
for (i = 0;i < lenb; i++){
b[lenb - i - 1] = b1[i] - 48;
}
for (i = 0; i < lena; i++){
x = 0;//初始化进位
for (j = 0; j < lenb; j++){
//模拟乘法竖式,进位、错位相加
c[i + j] = a[i] * b[j] + x + c[i + j];
x = c[i + j] / 10;//乘法进位
c[i + j] %= 10;//进位后保留个位
}
c[lenb + i] = x; //错位相加高位进位(先把进位加到高位)
}
lenc = lena + lenb;//两个非零因数相乘,积的位数要么是两个因数位数之和,要么是两个因数位数之和-1
//检查最高位是否为0,如果为0,退一位,while循环可以保证即使因数是0也能输出正确的结果而不输出多余前导0
while (c[lenc] == 0 && lenc > 0){
lenc--;
}
for (i = lenc; i >= 0; i--){
cout<<c[i];
}
return 0;
}