文章目录
- 高精度加法
- 题目描述
- 解法
- 高精度减法
- 题目描述
- 解法
- 讲解
- 高精度乘法
- 题目描述
- 解法
- 讲解
- 高精度除法
- 题目描述
- 解法
- 讲解
本文主要讲解高精度计算,包括加法、减法、乘法和除法。
对于Python选手,python自带高精度计算;Java也有BigInteger类。但是对于C选手和C++选手,高精度计算的算法还是很重要的。
java相关的大数类可以参见:Java【大数类】整理
高精度加法
题目描述
给定两个正整数(不含前导 0),计算它们的和。
数据范围
1 ≤ 整数长度 ≤ 100000
解法
cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B) {
if (A.size() < B.size()) return add(B, A);
vector<int> C;
int t = 0; // t是进位
for (int i = 0; i < A.size(); ++i) {
t += A[i];
if (i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(t);
return C;
}
int main()
{
string a, b;
vector<int> A, B;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - '0');
vector<int> C = add(A, B);
for (int i = C.size() - 1; i >= 0; --i) printf("%d", C[i]);
return 0;
}
高精度减法
题目描述
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
数据范围
1 ≤ 整数长度 ≤ 10^5
解法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(vector<int> &a, vector<int> &b) {
/* 判断是否 a 大于等于 b */
int an = a.size(), bn = b.size();
if (an != bn) return an > bn;
for (int i = an - 1; i >= 0; i--) { // 从最高位开始比较
if (a[i] != b[i]) {
return a[i] > b[i];
}
}
return true;
}
vector<int> sub(vector<int> &a, vector<int> &b) {
int an = a.size(), bn = b.size();
vector<int> c;
int t = 0; // t表示是否借位
for (int i = 0; i < an; i++) {
a[i] -= t; // 减去借位
if (i < bn) a[i] -= b[i];
c.push_back((a[i] + 10) % 10);
if (a[i] < 0) t = 1;
else t = 0;
}
while (c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
int main()
{
string a, b;
vector<int> A, B, C;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - '0');
if (cmp(A, B)) C = sub(A, B);
else {
printf("-");
C = sub(B, A);
}
for (int i = C.size() - 1; i >= 0; --i) printf("%d", C[i]);
return 0;
}
讲解
注意点包括:
判断a和b的大小;去除结果末尾的所有0;使用(t+10)%10;
高精度乘法
题目描述
给定两个非负整数(不含前导 0) A 和 B,请你计算 A×B 的值。
数据范围
1 ≤ A的长度 ≤ 100000,
0 ≤ B ≤ 10000
解法
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> mul(vector<int> A, int b) {
int t = 0; // t类似加法中的进位
vector<int> C;
for (int i = 0; i < A.size() || t; ++i) {
if (i < A.size()) t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); // 删除前导零
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A, C;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
C = mul(A, b);
for (int i = C.size() - 1; i >= 0; --i) printf("%d", C[i]);
return 0;
}
讲解
与加法类似。
高精度除法
题目描述
给定两个非负整数(不含前导 0) A,B,请你计算 A/B 的商和余数。
数据范围
1 ≤ A的长度 ≤ 100000,
1 ≤B ≤ 10000,
B 一定不为 0
解法
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> div(vector<int> a, int b, int &r) {
vector<int> c;
for (int i = a.size() - 1; i >= 0; --i) {
r = r * 10 + a[i];
c.push_back(r / b);
r %= b;
}
reverse(c.begin(), c.end());
while (c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A, C;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
int r = 0; // r是余数
C = div(A, b, r);
for (int i = C.size() - 1; i >= 0; --i) printf("%d", C[i]);
printf("\n%d\n", r);
return 0;
}
讲解
与 加减乘 不同,除法是从高位开始的。