高精度乘法基本算法

高精度乘法基本算法,两段,其实两段是同一种方法,第二段稍做优化。只是将计算结果显示到屏幕上。

所谓高精度乘法,是指计算超过标准数据类型能够表达的计算范围的乘法计算。

如果计算机结果已经超过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;
} 



猜你喜欢

转载自blog.csdn.net/qiminghang/article/details/81046179