🧮 C++高精度运算
电脑里一个 int 最大才到二十多亿,可要是算「两个一百位的数相加」,直接存就爆了。高精度运算的办法像我们手算列竖式:把超长的数拆成一位一位,一格存一位,再按竖式的规矩进位、借位。这一页就把这个「竖式模拟器」学起来。
考纲知识点:C++数组模拟高精度加法、减法、乘法、除法
📖
考纲 · 知识点详述
摘自《CCF编程能力等级认证 C++&Python 认证标准》C++ 五级
- (2)掌握C++数组模拟高精度加法、减法、乘法和除法的相关知识。
📚
先学一学
花 5 分钟读完下面 5 课,再去闯关就不慌啦
1
🏗️ 为什么需要高精度:一格装不下就用一排格子
C++ 的 int 大约能存到 21 亿,long long 也最多到「9 后面 18 个 0」左右。可要算的数是几百位(比如 2 的 1000 次方),没有一种现成整数类型装得下。怎么办?像算盘一样把数拆开:每一位数字放数组的一格里。
📦 一位存一格:把 12345 放进去
看得懂就好,不用背:
string s = "12345";
int a[100] = {};
for (int i = 0; i < s.size(); i++)
a[i] = s[s.size() - 1 - i] - '0';
int a[100] = {};
for (int i = 0; i < s.size(); i++)
a[i] = s[s.size() - 1 - i] - '0';
关键技巧:把个位放到 a[0]、十位放 a[1]……也就是倒着存。这样做加法进位时,进到「下一位」就是数组下标加 1,方便极了!
💡 口诀:个位放开头、倒着存数字;进位就往后挪一格,下标加 1 就进位。
2
➕ 高精度加法:满 10 就向前进 1
和手算一模一样:从个位(下标 0)开始,同位相加,满 10 向前进 1。比如算 35 + 78:个位 5+8=13,写下 3、进 1;十位 3+7+1=11,写下 1、进 1;最高位再写 1 → 结果是 113。
💻 读代码:高精度加法核心循环
看得懂就好,不用背:
int carry = 0;
for (int i = 0; i < maxLen; i++){
int sum = a[i] + b[i] + carry;
a[i] = sum % 10; // 这一位留下个位
carry = sum / 10; // 满 10 的部分进到下一位
}
for (int i = 0; i < maxLen; i++){
int sum = a[i] + b[i] + carry;
a[i] = sum % 10; // 这一位留下个位
carry = sum / 10; // 满 10 的部分进到下一位
}
carry 就是「进上去的 1」;循环结束若 carry 还是 1,就在最高位再补一个 1。
💡 口诀:同位相加加进位,留个位、进十位;进位别忘了补到最前面。
3
➖ 高精度减法:不够减就向高位借 1 当 10
减法从个位开始同位相减:够减直接减,不够减就向高位借 1 当 10。算 523 − 46:个位 3 不够减 6,向十位借 1,13−6=7;十位原来 2 被借走变 1,1 不够减 4,再向百位借 1 变 11,11−4=7;百位 5 被借走变 4 → 477。
⚠️ 减法要当心的事
· 先判断谁大:保证大数减小数,结果才不会是负的绕圈;若 a 小于 b,先输出负号再算 b − a。
· 借位标记:当前位置不够减时,给下一位记「欠 1」。
· 结果前面可能多出 0(比如 1000 − 999 = 0001),输出前要把开头的 0 去掉。
· 借位标记:当前位置不够减时,给下一位记「欠 1」。
· 结果前面可能多出 0(比如 1000 − 999 = 0001),输出前要把开头的 0 去掉。
💡 口诀:减法是「不够借 1 当 10」;大减小加负号,开头的 0 要抹掉。
4
✖️ 高精度乘法:每一位都乘一遍,错位相加
乘法也照竖式来:第二个数的每一位都要去乘第一个数的每一位,得到的部分积按位置错开累加。比如 123 × 45:先用 5 乘 123 得 615;再用 4 乘 123 得 492,但 4 是十位,所以结果要左移一位写(相当于 4920);最后 615 + 4920 = 5535。
💻 读代码:乘法累加骨架
看得懂就好,不用背:
for (int i = 0; i < lenA; i++)
for (int j = 0; j < lenB; j++)
ans[i + j] += a[i] * b[j];
// 最后再统一处理进位:每格 %10 留下个位,/10 加到下一格
for (int j = 0; j < lenB; j++)
ans[i + j] += a[i] * b[j];
// 最后再统一处理进位:每格 %10 留下个位,/10 加到下一格
下标 i + j 就是「错位」的落点:第二位乘的结果天然落在更高一位上。
💡 口诀:每个数字互乘一遍,落在 i+j 格;先累加、再一次进位。
5
➗ 高精度除法:从高位一位一位「试商」
🧪 除法怎么竖式
加、减、乘都是从低位(个位)开始;唯独除法反过来,从最高位开始:把当前「剩余的数」拿出来,看看能除以除数几次(这叫试商),写下商,余数留下拼到下一位。除数是普通整数时好办;除数是另一个大数时更麻烦,通常会转成「减法反复减」或二分试商。
💡 口诀:加减乘从个位起,除法从最高位试;余数留下来接着除。
🆚 四则运算一表看清
· 加法:从个位,满十进一。
· 减法:从个位,不够借一当十,先保证大减小。
· 乘法:每一位互乘、错位累加,再一次进位。
· 除法:从最高位试商,余数参与下一位。
· 减法:从个位,不够借一当十,先保证大减小。
· 乘法:每一位互乘、错位累加,再一次进位。
· 除法:从最高位试商,余数参与下一位。
💡 口诀:加进位、减借位、乘错位、除试商——竖式四兄弟,规矩各不同。
🌟 行业实际:加密和银行都在用大数
网络加密要用几百位的大数做运算;银行对账单、身份证校验、天体距离计算也常超过普通整数范围。真实世界里「一个格子装不下」是常有的事,会模拟竖式就能算别人算不了的大数。
🎯
闯关小锦囊 · 考点提醒
- 高精度:整数类型装不下超长数,用数组一位存一格,个位放数组开头(倒着存)。
- 加法:从个位同位相加,满 10 向前进 1,最后进位别忘了补到最高位。
- 减法:不够减向高位借 1 当 10;先保证大减小,输出前去掉开头的 0。
- 乘法:每一位互乘,部分积累加到 i+j 格,再一次进位。
- 除法:从最高位开始逐位试商,余数接着除。
- 低位在前时借位写法:向高一位借 1 是 a[i + 1]--,自己这一位补 a[i] += 10;处理进位要把当前格 c[k] 和 carry 相加。
- 乘法运算时间和两个数的位数都有关(每位乘每位),不是只看较长的那一个。
🎮
学完了?来闯关!
下面 14 个小挑战,点一点就能玩
Demo 原型 · 每个知识点独立页面 · 暂不含真实编译与进度存储。