高精度

存储方式:数组(可用vector,自带size函数),由低位向高位存各位数字

运算方式:模拟

高精度加法

例:$123+89$

0 1 2 3
A 3 2 1 0
B 9 8 0 0
C 2 1 2 0

思路:

  • 输入两个字符串,并转化成vector
  • 循环至两数的最高位,每次判断两个数是否有第$i$位,若有,$t$加上第$i$位,和的第$i$位$=t %10,t/=10$
  • 循环完后判断$t$是否为$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
#include<bits/stdc++.h>
using namespace std;

string a,b;
vector<int>A,B;

vector<int> add(vector<int> &x,vector<int> &y){
vector<int>s;
int t=0;
for(int i=0;i<x.size()||i<y.size();i++){
if(i<x.size())t+=x[i];
if(i<y.size())t+=y[i];
s.push_back(t%10);
t/=10;
}
if(t)s.push_back(t);
return s;
}

int main(){
cin >> a >> b;
for(int i=a.length()-1;i>=0;i--){
A.push_back(a[i]-'0');
}
for(int i=b.length()-1;i>=0;i--){
B.push_back(b[i]-'0');
}
auto C=add(A,B);
for(int i=C.size()-1;i>=0;i--){
cout << C[i];
}
return 0;
}

高精度减法

  • 判断$A,B$的大小

    当长度不同时,长度越短,大小越小

    当长度相同时,从高位循环到低位,若当前位不同,则当前位小的数小

  • 循环到最高位,首先$t=A[i]-t$(减去借位),然后如果$B$有第$i$位,$t$减去$B[i]$,当前位等于$(t+10)%10$(防止负数),若$t$为负数,则$t=1$(借位标记),否则$t=0$

  • 循环结束去掉前导$0$

    从最高位开始循环直到$size()==1$(结果为$0$时保留),若当前位是0($C.back()==0$),则删除当前位($C.pop_back()$),若当前位不为零,则跳出循环

代码实现:

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
#include<bits/stdc++.h>
using namespace std;

string a,b;
vector<int>A,B;

bool operator<(vector<int>x,vector<int>y){
if(x.size()==y.size()){
for(int i=x.size()-1;i>=0;i--){
if(x[i]!=y[i])return x[i]<y[i];
}
return 0;
}
return x.size()<y.size();
}

vector<int> sub(vector<int> &x,vector<int> &y){
vector<int>s;
int t=0;
for(int i=0;i<x.size();i++){
t=x[i]-t;
if(i<y.size())t-=y[i];
s.push_back((t+10)%10);
if(t<0)t=1;
else t=0;
}
while(s.size()>1&&s.back()==0){
s.pop_back();
}
return s;
}

int main(){
cin >> a >> b;
for(int i=a.length()-1;i>=0;i--){
A.push_back(a[i]-'0');
}
for(int i=b.length()-1;i>=0;i--){
B.push_back(b[i]-'0');
}
vector<int>C;
bool flag=0;
if(A<B){
C=sub(B,A);
cout << '-';
}
else{
C=sub(A,B);
}
for(int i=C.size()-1;i>=0;i--){
cout << C[i];
}
return 0;
}

高精度乘法

  • 双重循环,$C[i+j]=A[i]*B[j]$,处理进位
  • 循环结束去掉前导$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
41
42
43
44
45
46
47
48
#include<bits/stdc++.h>
using namespace std;

string a,b;
vector<int>A,B;

vector<int> mul(vector<int> &x,vector<int> &y){
vector<int>s;
for(int i=0;i<y.size();i++){
for(int j=0;j<x.size();j++){
if(j+i<s.size()){
s[j+i]+=x[j]*y[i];
}
else{
s.push_back(x[j]*y[i]);
}
if(s[j+i]>9){
if(j+i+1<s.size()){
s[j+i+1]+=s[j+i]/10;
s[j+i]%=10;
}
else{
s.push_back(s[j+i]/10);
s[j+i]%=10;
}
}
}
}
while(s.size()>1&&s.back()==0){
s.pop_back();
}
return s;
}

int main(){
cin >> a >> b;
for(int i=a.length()-1;i>=0;i--){
A.push_back(a[i]-'0');
}
for(int i=b.length()-1;i>=0;i--){
B.push_back(b[i]-'0');
}
auto C=mul(A,B);
for(int i=C.size()-1;i>=0;i--){
cout << C[i];
}
return 0;
}

高精度除法

  • 输入高精度数$A$和长整型数$b$
  • 初始$r=0$,从高位向低位循环,每次$r=r*10+A[i]$,则答案的第$i$位为$r/b$,$r=r%b$
  • 结束后答案数组是由高位向低位存储,所以翻转数组($reserve(C.begin(),C.end())$)
  • 去掉前导$0$
  • $r$即为余数(传入$r$时用$&r$,可以实时改变$r$的真实值)

代码实现:

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
#include<bits/stdc++.h>
using namespace std;

string a;
long long b;
vector<int>A;

vector<int> div(vector<int> &x,long long y,long long &r){
vector<int>s;
r=0;
for(int i=A.size()-1;i>=0;i--){
r=r*10+A[i];
s.push_back(r/y);
r%=y;
}
reverse(s.begin(),s.end());
while(s.size()>1&&s.back()==0){
s.pop_back();
}
return s;
}

int main(){
cin >> a >> b;
for(int i=a.length()-1;i>=0;i--){
A.push_back(a[i]-'0');
}
long long r;
auto C=div(A,b,r);
for(int i=C.size()-1;i>=0;i--){
cout << C[i];
}
cout << endl << r;//余数
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
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
95
96
97
#include<bits/stdc++.h>
using namespace std;

vector<int> change(string s){//字符串转vector数组
vector<int>to;
for(int i=s.length()-1;i>=0;i--){
to.push_back(s[i]-'0');
}
return to;
}

vector<int> add(vector<int> &x,vector<int> &y){//加法
vector<int>s;
int t=0;
for(int i=0;i<x.size()||i<y.size();i++){
if(i<x.size())t+=x[i];
if(i<y.size())t+=y[i];
s.push_back(t%10);
t/=10;
}
if(t)s.push_back(t);
return s;
}

bool operator<(vector<int>x,vector<int>y){
if(x.size()==y.size()){
for(int i=x.size()-1;i>=0;i--){
if(x[i]!=y[i])return x[i]<y[i];
}
return 0;
}
return x.size()<y.size();
}

vector<int> sub(vector<int> &x,vector<int> &y){//减法
vector<int>s;
int t=0;
for(int i=0;i<x.size();i++){
t=x[i]-t;
if(i<y.size())t-=y[i];
s.push_back((t+10)%10);
if(t<0)t=1;
else t=0;
}
while(s.size()>1&&s.back()==0){
s.pop_back();
}
return s;
}

vector<int> mul(vector<int> &x,vector<int> &y){//乘法
vector<int>s;
for(int i=0;i<y.size();i++){
for(int j=0;j<x.size();j++){
if(j+i<s.size()){
s[j+i]+=x[j]*y[i];
}
else{
s.push_back(x[j]*y[i]);
}
if(s[j+i]>9){
if(j+i+1<s.size()){
s[j+i+1]+=s[j+i]/10;
s[j+i]%=10;
}
else{
s.push_back(s[j+i]/10);
s[j+i]%=10;
}
}
}
}
while(s.size()>1&&s.back()==0){
s.pop_back();
}
return s;
}

vector<int> div(vector<int> &x,long long y,long long &r){//除法
vector<int>s;
r=0;
for(int i=x.size()-1;i>=0;i--){
r=r*10+x[i];
s.push_back(r/y);
r%=y;
}
reverse(s.begin(),s.end());
while(s.size()>1&&s.back()==0){
s.pop_back();
}
return s;
}

int main(){

return 0;
}