高精加和高精乘(正整数)

高精加和高精乘

仅正整数

高精度加法

实现思路

核心:模拟笔算

即用数组里的每个元素来作为笔算加法竖式的每一位

为规范化以及移植性,输入输出均为string

步骤:

  1. 将字符串存入数组a和b
  2. 另外定义两个数组s和c,分别存储每一位的结果值和进位值
  3. c[0]的值为0,s[i]的值是(a[i]+b[i]+c[i])%10,c[i]的值是(a[i]+b[i]+c[i])/10,以此类推,完成所有位数的相加
  4. 将数组元素存入新定义的string中

注意事项:

  • 对数组int a[10]的理解:包含a[0],a[1],a[2],…,a[9]共10个元素
  • string类:按顺序往里填入元素时(步骤4),用str+ = '单个元素',表示结束时如果用赋值的方法(比如str[2] = '\0';),可能引起后续对该字符串的操作出错
  • 输出string类:调用函数 cout<<sum.c_str()<<endl;(因为不能直接输出)(可以试试)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<iostream>
using namespace std;
int getN(string a)
{
int n=0;
while(a[n]!='\0')n++;
return n;
}
int main()
{
string a,b;
cin>>a>>b;
int an=getN(a);
int bn=getN(b);
int N=an;
if(an<bn)N=bn;
int aa[N]={0};
for(int i=0;i<an;i++)aa[i]=a[an-1-i]-'0';
int bb[N]={0};
for(int i=0;i<bn;i++)bb[i]=b[bn-1-i]-'0';
int s[N+1],c[N+1];
c[0]=0;
for(int i=0;i<N;i++)
{
s[i]=(aa[i]+bb[i]+c[i])%10;
c[i+1]=(aa[i]+bb[i]+c[i])/10;
}
s[N]=c[N];
string sum;
if(s[N]==0)
{
for(int i=0;i<N;i++)
sum+=s[N-1-i]+'0';
}
else
{
for(int i=0;i<=N;i++)
sum+=s[N-i]+'0';
}
cout<<sum.c_str()<<endl;

system("pause");

return 0;
}

高精度乘法

实现思路

先实现个位数乘多位的整数(输入输出均为字符串),再在经过对应补零操作后用高精加,实现高精度乘法

至于为什么不用高精度累加来代替乘法,原因:肉眼可见的复杂度

个位数乘多位整数

注意事项:同高精度加法,不再赘述

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
using namespace std;

int getN(string a)
{
int n=0;
while(a[n]!='\0')n++;
return n;
}

int main()
{
int a;
string b;
cin>>a>>b;
int n=getN(b);
int bb[n];
for(int i=0;i<n;i++)
bb[i]=b[n-1-i]-'0';
int c[n+1]={0};
int s[n+1]={0};
for(int i=0;i<n;i++)
{
s[i]=(a*bb[i]+c[i])%10;
c[i+1]=(a*bb[i]+c[i])/10;
}
s[n]=c[n];
string r;
if(s[n]==0)
{
for(int i=0;i<n;i++)
r+=s[n-1-i]+'0';
}
else
{
for(int i=0;i<=n;i++)
r+=s[n-i]+'0';
}
cout<<r.c_str()<<endl;
}
多位数乘多位数

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include<bits/stdc++.h>
using namespace std;

int getN(string a)
{
int n=0;
while(a[n]!='\0')n++;
return n;
}

string add(string a,string b)
{
int an=getN(a);
int bn=getN(b);
int N=an;
if(an<bn)N=bn;
int aa[N]={0};
for(int i=0;i<an;i++)
aa[i]=a[an-1-i]-'0';
int bb[N]={0};
for(int i=0;i<bn;i++)
bb[i]=b[bn-1-i]-'0';
int s[N+1],c[N+1];
c[0]=0;
for(int i=0;i<N;i++)
{
s[i]=(aa[i]+bb[i]+c[i])%10;
c[i+1]=(aa[i]+bb[i]+c[i])/10;
}
s[N]=c[N];
string sum;
if(s[N]==0)
{
for(int i=0;i<N;i++)
sum+=s[N-1-i]+'0';
}
else
{
for(int i=0;i<=N;i++)
sum+=s[N-i]+'0';
}
return sum;
}

string multi_1(int a,string b)
{
int n=getN(b);
int bb[n];
for(int i=0;i<n;i++)
bb[i]=b[n-1-i]-'0';
int c[n+1]={0};
int s[n+1]={0};
for(int i=0;i<n;i++)
{
s[i]=(a*bb[i]+c[i])%10;
c[i+1]=(a*bb[i]+c[i])/10;
}
s[n]=c[n];
string r;
if(s[n]==0)
{
for(int i=0;i<n;i++)
r+=s[n-1-i]+'0';
}
else
{
for(int i=0;i<=n;i++)
r+=s[n-i]+'0';
}
return r;
}

string add_0(int a,string b)
{
for(int i=0;i<a;i++)
{
b+="0";
}
return b;
}

int main()
{
string a,b;
cin>>a>>b;
int an=getN(a);
int aa[an];
for(int i=0;i<an;i++)
aa[i]=a[an-1-i]-'0';
string c="0";
for(int i=0;i<an;i++)
c=add(add_0(i,multi_1(aa[i],b)),c);
cout<<c.c_str()<<endl;
}

总结

核心思想是模拟竖式计算

注意string类的用法

PS: 其实这一篇博客还是为了测试


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!