← 目录 / 算法文档 · 模块一 数学基础 / 1.12 高精度除法

1.12 高精度除法

除法是四则运算里唯一一个要从最高位开始算的——模拟竖式除法,带着余数从左往右一路除下去。

本页目录
① 核心思路:从最高位开始

前面三节(加、减、乘)都是从最低位(个位)算起,这也是为什么之前都要把数字倒序存进数组。但除法完全反过来——回忆一下小学做除法竖式的过程:永远是从数字的最高位开始,一位一位地"落下来"继续除,这一点和加减乘正好相反。

正因为方向不同,高精度除法(这里特指"高精度 ÷ 低精度",也就是大数除以一个 long long 范围内的整数)不需要把数字倒序存储,直接按字符串的正常顺序(从左到右,最高位在前)处理反而更方便。

加、减、乘:从最低位开始
进位/借位都是"低位影响高位",数组倒序存储(下标 0 是个位),从下标 0 往大的方向算。
除法:从最高位开始
余数是"高位传给低位",直接按字符串正常顺序(最高位在前)从左到右处理,不需要倒序存储。

具体做法:维护一个"当前余数",从字符串最左边的字符开始,每次把"当前余数 × 10 + 新落下来的这一位数字"作为新的被除数,除以除数得到商的这一位,再更新余数,一路做到字符串末尾。

竖式演示:1035 ÷ 23 = 45(正好是上一节乘法例子的逆运算)
1
余数 0×10+1 = 1,1÷23 商 0 余 1
0
余数 1×10+0 = 10,10÷23 商 0 余 10
3
余数 10×10+3 = 103,103÷23 商 4 余 11
5
余数 11×10+5 = 115,115÷23 商 5 余 0
四步的商依次是 0 0 4 5,去掉前导 0 后就是 45,余数最终是 0(整除)。每一步的"新余数"都是由"上一步余数 × 10 + 当前这一位数字"得到的,这正是竖式除法里"落下一位接着除"的数学本质。
② 完整代码:高精度 ÷ 低精度
C++ · 高精度除以低精度
1string s;
2long long divisor;
3cin >> s >> divisor; // s 是被除数(字符串,不需要倒序),divisor 是除数
4
5string quotient = ""; // 商,边算边往后追加字符
6long long remainder = 0; // 当前余数
7
8for (int i = 0; i < (int)s.size(); i++) // 从最高位(下标0)开始往后遍历
9{
10 remainder = remainder * 10 + (s[i] - '0'); // 落下一位,拼成新的被除数
11 quotient += (char)(remainder / divisor + '0'); // 这一位的商
12 remainder %= divisor; // 更新余数,带到下一位继续用
13}
14
15// 去掉商前面多余的 0(比如 0045 应该只输出 45)
16int start = 0;
17while (start < (int)quotient.size() - 1 && quotient[start] == '0')
18{
19 start++;
20}
21
22cout << quotient.substr(start) << endl; // 商
23cout << remainder << endl; // 最后剩下的余数
📖
为什么这版代码不需要 vector?因为处理顺序和字符串本身的顺序(最高位在前)完全一致,不需要像加减乘那样"倒过来存"才好操作,直接对 string 按下标从 0 开始正向遍历即可,商也直接拼接成一个新的字符串,反而比前三节更简洁。
③ 高精度 ÷ 高精度:了解即可

如果除数本身也是一个大数(不能存进一个 long long),问题会复杂得多——每一位商是多少,不能像上面那样直接用 / 算出来,往往需要"试商":猜一个商的值,用竖式乘法算出"商 × 除数",再和当前余数比较大小(用到 1.10 节的比较方法),反复调整,或者用二分查找加速试商的过程。

🎓
竞赛中出现频率不高:"高精度 ÷ 高精度"实现起来繁琐、代码量大,出现在入门到进阶阶段题目里的概率相对较低,本节不展开完整实现,了解"试商 + 试乘 + 比较"这个大致思路即可。如果真的遇到这类题目,可以再针对性地深入学习。
④ 四则运算小结

把 1.9~1.12 四节的内容汇总成一张表,方便复习和查阅:

运算处理方向核心操作时间复杂度
加法 从低位到高位 逐位相加,满 10 进位 O(len)
减法 从低位到高位 先比大小,逐位相减,不够借位 O(len)
乘法 先按位置累加,再统一处理 a[i]*b[j] 累加到第 i+j 位,最后统一进位 O(len1 × len2)
除法 从高位到低位 余数×10+新一位,除以除数得到商 O(len)(仅限除以低精度)
⑤ 常见陷阱

把本节内容汇总成几条最容易踩坑的规则:

1
方向搞反:除法必须从最高位开始处理,如果不小心沿用了加减乘"从最低位开始、倒序存储"的思路,会得到完全错误的结果。四种运算里,除法是唯一一个"方向不同"的,务必单独留意。
2
商的前导 0 没有去掉:如果被除数的最高几位都小于除数(比如例子中前两步商都是 0),商字符串的开头会带着若干个 0,直接输出会变成"0045"这种带多余 0 的结果,必须先跳过前导 0 再输出。
3
用 int 而不是 long long 存储余数和除数:虽然余数理论上小于除数,但中间计算 remainder * 10 + 下一位 时数值会先变大再取模,如果除数本身接近 int 的上限,中间结果可能超出 int 范围,建议统一用 long long 存储余数和除数,避免溢出。
4
除数为 0 没有特判:和普通除法一样,高精度除法的除数同样不能是 0。题目通常会保证除数非零,但自己测试代码时如果误传入 0,程序会直接崩溃(除零错误),调试时要留意这一点。