高精度
高精度乘法
高精度乘低精度
1 | // A 是大数(vector),b 是普通整数(int) |
高精度乘高精度

这个公式的证明其实非常直观,它的核心在于十进制数值的展开式。
我们可以通过以下三个步骤来证明:
1. 数值的数学表示
任何一个多位整数都可以写成以 $10$ 为底的幂级数形式。
假设大整数 $A$ 有 $n$ 位,大整数 $B$ 有 $m$ 位:
其中 $A[i]$ 是 $A$ 从右往左数第 $i$ 位上的数字(即权重为 $10^i$ 的位)。
2. 乘法的展开(多项式乘法)
当我们计算 $A \times B$ 时,根据乘法分配律,相当于 $A$ 中的每一项都要乘以 $B$ 中的每一项:
展开后的每一项可以写成:
3. 指数定律的运用
注意看结果中的幂次部分:
这告诉我们:$A$ 的第 $i$ 位与 $B$ 的第 $j$ 位相乘的结果,其权重是 $10^{i+j}$。
在我们的结果数组 $C$ 中,$C[k]$ 存储的就是权重为 $10^k$ 的部分。因此,所有满足 $i + j = k$ 的乘积项 $(A[i] \times B[j])$ 都应该累加到 $C[k]$ 上。
举个简单的例子:$12 \times 34$
- $A = 12 = 1 \cdot 10^1 + 2 \cdot 10^0 \implies A[1]=1, A[0]=2$
- $B = 34 = 3 \cdot 10^1 + 4 \cdot 10^0 \implies B[1]=3, B[0]=4$
我们来算 $C[i+j]$:
- 当 $i=0, j=0$:$i+j=0$。$C[0] = A[0] \times B[0] = 2 \times 4 = 8$
- 当 $i=0, j=1$:$i+j=1$。$C[1] += A[0] \times B[1] = 2 \times 3 = 6$
- 当 $i=1, j=0$:$i+j=1$。$C[1] += A[1] \times B[0] = 1 \times 4 = 4$(此时 $C[1] = 6+4=10$)
- 当 $i=1, j=1$:$i+j=2$。$C[2] = A[1] \times B[1] = 1 \times 3 = 3$
目前 $C$ 数组为:{8, 10, 3}(对应 $8 \cdot 10^0 + 10 \cdot 10^1 + 3 \cdot 10^2$)
最后处理进位:
- $C[0]=8$
- $C[1]=10 \implies$ 留 $0$,进 $1$
- $C[2]=3 + 进位1 = 4$
结果为:$408$。 计算正确!
结论
这个公式的本质是:高精度乘法 = 多项式乘法 + 进位处理。
由于 $10^i \cdot 10^j = 10^{i+j}$,所以 $A[i] \cdot B[j]$ 必须且只能贡献给结果数组中的第 $i+j$ 位。
1 | vector<int> mul_big(vector<int> &A, vector<int> &B) { |
洛谷13031
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
using namespace std;
vector<int> stringToV(string a){
vector<int> n;
int len=a.length();
for(int i=len-1;i>=0;i--){
int num=a[i]-'0';
n.push_back(num);
}
return n;
}
vector<int> highMul(string s1,string s2){
if(s1=="0" || s2=="0") return {0};
vector<int> a=stringToV(s1);
vector<int> b=stringToV(s2);
vector<int> c(a.size()+b.size(),0);
for(int i=0;i<a.size();i++){
for(int j=0;j<b.size();j++){
c[i+j]+=a[i]*b[j];
}
}
int t=0;
for(int i=0;i<c.size();i++){
t+=c[i];
c[i]=t%10;
t/=10;
}
while(c.size()>1 && c.back()==0) c.pop_back();
return c;
}
int main(){
string a,b;
cin>>a>>b;
vector<int> ans=highMul(a,b);
for(int i=ans.size()-1;i>=0;i--) cout<<ans[i];
cout<<endl;
return 0;
}
高精度加法
1 |
|
高精度减法
要求 A >= B,核心是借位处理,(t + 10) % 10 这一行:t 为负时借位,加 10 取模得到当前位。
1 | // 判断 A >= B |
主函数里先判断大小:A >= B 直接减;否则交换两个数,输出时在前面加个负号。竞赛里甚至可以只留 sub 这一个函数。
字符串简化版(不依赖 vector,直接 string 操作):
1 | void exchange(string &a, string &b) { |
高精度除法(高精度 / 低精度)
从高位往低位做除法,余数 r 带上低一位继续除;结束后去掉前导 0。
1 | // A / b,r 返回余数 |
除法在四则运算里相对少见,但和高精乘(多项式乘法 + 统一进位)、高精减(借位)、高精加(进位)放在一起,一套四则运算就齐了。