为什么要用高精度来计算乘法?
当进行整数计算的时候, 数据超过 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;
}
以上就是高精度乘法的全部内容了