【C++】高精度乘法(模拟算法)代码讲解

为什么要用高精度来计算乘法?

当进行整数计算的时候, 数据超过 8Byte 后,C++就没有对应的数据类型就行表达。这就是为什么 C++ 需要高精度计算。


要用什么手段来计算超出long long范围的两数相乘?

我们可以用char数组来记载数字,实现超出long long范围两数相乘


代码

#include <iostream>
#include <cstring>
using namespace std;
int main(){
	char s1[512],s2[512];
	int n1[512],n2[512];
	int ans[512] = {};
	scanf("%s %s",&s1,&s2);
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int lenans = 0;
	
	for (int i = 0;i<len1;i++){
		n1[i] = s1[len1-1-i] - '0';
	}
	for (int i = 0;i<len2;i++){
		n2[i] = s2[len2-1-i] - '0';
	}
	int t = 0;
	for (int  i = 0;i<len1;i++){
		for (int  j = 0;j<len2;j++){
			ans[i+j] += n1[i]*n2[j]+t;
			t = ans[i+j]/10;
			ans[i+j]%=10;
		}
		ans[len2+i] = t;
		t = 0;
	}
	lenans = len1+len2;
	while (ans[lenans] == 0 && lenans>0){
		lenans--;
	}
	for (int  i = lenans;i>=0;i--){
		printf("%d",ans[i]);
	}
	return 0;
} 

代码讲解

首先,我们要输入获取两个超大数字,并且存入char数组之中,这应该很简单,没什么问题,就不讲解了

#include <iostream>
#include <cstring>
using namespace std;
int main(){
    char s1[512],s2[512];
    int n1[512],n2[512];
    scanf("%s%s",s1,s2);    

    return 0;
}

接着,我们要模拟平时做竖式计算乘法一样,(如图)倒序将上面的数字一个一个乘以b,然后将进位的数存储在变量里面,在下一次计算的时候加上我们的上一位的进位:

现在我们用代码表示出来:

1.因为我们做竖式计算的时候是从右往左计算的,所以我们要把输入的数字倒叙存储并且转换为int类型。

#include <iostream>
#include <cstring>
using namespace std;
int main(){
    char s1[512],s2[512];
    int n1[512],n2[512];
    int ans[512] = {};
    scanf("%s%s",s1,s2);//输入char数字时不用&
    int l1 = strlen(s1);//计算长度
    int l2 = strlen(s2);
    for (int i = l1-1;i>=0;i--){
        n1[l1-1-i] = s1[i] - '0';
    }
    for (int i = l2-1;i>=0;i--){
        n2[l2-1-i] = s2[i] - '0';
    }

2.模拟竖式计算过程

核心代码:

#include <iostream>
#include <cstring>
using namespace std;
int main(){
    
    for (int i = 0;i<l1;i++){
        for (int  j = 0;j<l2;j++){
            ans[i]+=n1[i]*=n2[j];//计算当前这位
        }
        ans[i]+=in;//加上上一次的进位
        in = ans[i]/10;//计算进位
        ans[i]%=10;//取个位
    }

    return 0;
}

#include <iostream>
#include <cstring>
using namespace std;
int main(){
	char s1[512],s2[512];
	int n1[512],n2[512];
	int ans[512] = {};
	scanf("%s %s",&s1,&s2);
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int lenans = 0;
	for (int i = 0;i<len1;i++){
		n1[i] = s1[len1-1-i] - '0';
	}
	for (int i = 0;i<len2;i++){
		n2[i] = s2[len2-1-i] - '0';
	}
	int t = 0;
	for (int  i = 0;i<len1;i++){
		for (int  j = 0;j<len2;j++){
			ans[i+j] += n1[i]*n2[j]+t;
			t = ans[i+j]/10;
			ans[i+j]%=10;
		}
		ans[len2+i] = t;
		t = 0;
	}
	
	for (int  i = lenans;i>=0;i--){
		printf("%d",ans[i]);
	}
	return 0;
} 

3.我们先来输出:

如果前面的是0️⃣(前导零)的话我们就需要把这些0给删除掉。我们当然实现不了真正的删除,我们可以从前往后一个一个看,如果一直是零的话就一直往后扫描,直到遇到第一个不是零的数字时停止,然后从第一个不是0的数字开始输出就可以“删除”0了,代码如下:ji

#include <iostream>
#include <cstring>
using namespace std;
int main(){
	char s1[512],s2[512];
	int n1[512],n2[512];
	int ans[512] = {};
	scanf("%s %s",&s1,&s2);
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int lenans = 0;
	
	for (int i = 0;i<len1;i++){
		n1[i] = s1[len1-1-i] - '0';
	}
	for (int i = 0;i<len2;i++){
		n2[i] = s2[len2-1-i] - '0';
	}
	int t = 0;
	for (int  i = 0;i<len1;i++){
		for (int  j = 0;j<len2;j++){
			ans[i+j] += n1[i]*n2[j]+t;
			t = ans[i+j]/10;
			ans[i+j]%=10;
		}
		ans[len2+i] = t;
		t = 0;
	}
	lenans = len1+len2;
	while (ans[lenans] == 0 && lenans>0){
		lenans--;
	}
	for (int  i = lenans;i>=0;i--){
		printf("%d",ans[i]);
	}
	return 0;
} 

以上就是高精度乘法的全部内容了 

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值