高精度-加减乘

参考:【算法模板】高精度模板(带图详解)SuhyOvO的博客-CSDN博客

1.正整数加法

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
string add(string x, string y) {
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));

int la = x.length();
int lb = y.length();
int lc = max(la, lb); //加起来的数的长度不会超过原先两个数的长度最大值

//逆置字符串,从低位到高位
for (int i = 0; i < la; i++)
a[i] = x[la - i - 1] - '0';
for (int i = 0; i < lb; i++)
b[i] = y[lb - 1 - i] - '0';

for (int i = 0; i < lc; i++) { //其实就是竖式计算
c[i] += a[i] + b[i]; //两数相加,再加上前面计算的进位
c[i + 1] += c[i]/10; //把进位存到i+1位上
c[i] %= 10;
}

lc++;//如果有进位就多显示一位
while (lc > 1 && c[lc-1] == 0) lc--;//去除前面的前导零,防止后面逆置输出多余的零

//重新逆置,从高位到低位
string res = "";
for (int i = lc- 1; i >= 0; i--){
res.push_back(char(c[i] + '0'));
}
return res;
}

2.正整数减法

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
string sub(string sa, string sb){

memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
la = sa.length();
lb = ab.length();
lc = max(la, lb);//相减的数的长度不会超过原先两个数的长度最大值

string sub = "";
if(la < lb || (la == lb && (x[la-1]-'0' < y[lb-1]-'0'))){
swap(la, lb);
swap(sa, sb);
sub = "-";
}

//逆置字符串,从低位到高位
for (int i = 0; i < la; i++)
a[i] = x[la - i - 1] - '0';
for (int i = 0; i < lb; i++)
b[i] = y[lb - 1 - i] - '0';

for (int i = 0; i < lc; i++) {
if (a[i] < b[i]) {
a[i + 1] -= 1;//向高一位借位
a[i] += 10;//给当前位加10
}
c[i] = a[i] - b[i];//再两数相减
}

while ((c[lc - 1] == 0) && (lc > 1)) lc--;//去除前面的前导零,防止后面逆置输出多余的零

//重新逆置,从高位到低位
string res = "";
for (int i = lc-1; i >= 0; i--){
res.push_back(c[i] + '0');
}
return sub + res;
}

3.高精乘低精

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
string mul(string x, int y) {
la = x.length();
string ans = "";

if (x[0] == '-' && y > 0) { //对负号的处理
x = x.substr(1, la);
la--;
ans.push_back('-');
} else if (x[0] != '-' && y < 0) {
y = abs(y);
ans.push_back('-');
} else if (x[0] == '-' && y < 0) {
x = x.substr(1, la);
la--;
y = abs(y);
}

for (int i = 0; i < la; i++) {
a[i] = x[la - i - 1] - '0';
}

for (int i = 0; i < la; i++) {
a[i] = a[i] * y + tmp; //运算
tmp = a[i] / 10;//进位
a[i] %= 10;
}
//进位不为0
if (tmp != 0) {
a[la++] = tmp;
while (a[la - 1] > 0) { //刚存进去的进位,判断是否大于10需要进位
a[la] = a[la - 1] / 10;
a[la - 1] %= 10;
la++;
}
}
while ((a[la - 1] == 0) && (la > 1)) la--;

for (int i = la - 1; i >= 0; i--) {
ans.push_back(a[i] + '0');
}
return ans;
}

4.高精乘高精

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
string High_Mul(string x, string  y) {
string ans = "";
la = x.length();
lb = y.length();

if (x[0] == '-' && y[0] != '-') { //对负号的处理
x = x.substr(1,la--);
ans.push_back('-');
} else if (x[0] != '-' && y[0] == '-') {
y = y.substr(1,lb--);
ans.push_back('-');
} else if (x[0] == '-' && y[0] == '-') {
x = x.substr(1,la--);
y = y.substr(1,lb--);
}

for (int i = 0; i < la; i++)
a[i] = x[la - i - 1] - '0';
for (int i = 0; i < lb; i++)
b[i] = y[lb - 1 - i] - '0';

//长度最大变成两个数的长度之和
lc = la + lb ;

for (int i = 0; i < la; i++) {
for (int j = 0; j < lb; j++) {
c[i + j] += a[i] * b[j];//两数相乘,存到对应位置
c[i + j + 1] += c[i + j] / 10;//把进位加到前面一位上
c[i + j] %= 10;//取模存0-9的数
}
}

while ((c[lc - 1] == 0) && (lc > 1)) lc--;

for (int i = lc- 1; i >= 0; i--){
ans.push_back(c[i] + '0');
}
return ans;
}

5.高精除以低精

1
未完待续。。。≡(▔﹏▔)≡

高精度-加减乘
https://czwcugb.github.io/算法/未分类/高精度/
作者
ChenZhiwei
发布于
2025年1月12日
许可协议