前言在C中常规数据类型int、long long存在取值范围限制其中long long的最大值仅约9e18当需要处理数百位、数千位的超大整数如加密运算、大数据分析、竞赛真题中的大数计算时就需要借助高精度算法。高精度算法的核心思想是用数组/容器模拟大整数的每一位复刻手工竖式计算逻辑手动处理进位、借位彻底突破数据类型的位数限制。本文将从核心原理、代码实现、测试案例、避坑技巧四个维度详细讲解高精度加减乘除四大基础运算代码可直接复制使用新手也能快速上手。一、高精度算法核心预备知识1.1 核心存储规则高精度数的存储遵循「低位在前、高位在后」的原则原因是手工计算时进位、借位均从低位开始此存储方式可避免频繁移动数组元素简化运算逻辑。示例数字 123456 存储为 vectorint nums {6,5,4,3,2,1}其中下标0对应个位6下标1对应十位5依次类推下标5对应十万位1。1.2 通用辅助函数为简化代码先实现两个通用辅助函数后续所有运算均会复用避免重复编码#include iostream #include vector #include string #include algorithm using namespace std; // 辅助函数1字符串转高精度数组低位在前 vectorint strToBig(string s) { vectorint res; // 从字符串末尾高位遍历存入数组低位在前 for (int i s.size() - 1; i 0; i--) { res.push_back(s[i] - 0); // 字符转数字 } return res; } // 辅助函数2高精度数组转字符串高位在前用于输出 string bigToStr(vectorint num) { string res; // 跳过高位前导零避免输出 000123 这类结果 int i num.size() - 1; while (i 0 num[i] 0) i--; // 若全为零直接返回 0 if (i 0) return 0; // 从高位到低位拼接字符串 while (i 0) { res (char)(num[i] 0); i--; } return res; }二、高精度加法A B2.1 算法原理模拟手工加法从低位数组下标0开始逐位将A、B对应位的数字相加同时加上上一位的进位当前位结果 A[i] B[i] 进位% 10新的进位 A[i] B[i] 进位/ 10遍历完A、B所有位后若仍有进位进位≠0需将进位添加到结果的最高位。2.2 完整代码实现// 高精度加法A B返回结果低位在前 vectorint add(vectorint A, vectorint B) { vectorint res; int carry 0; // 进位初始为0 int i 0; // 遍历所有位直到A、B遍历完且进位为0 while (i A.size() || i B.size() || carry 0) { // 累加当前位数字若下标超出范围视为0 if (i A.size()) carry A[i]; if (i B.size()) carry B[i]; // 存入当前位结果 res.push_back(carry % 10); // 更新进位 carry / 10; i; } return res; } // 测试函数可直接运行 int main() { string a, b; cin a b; vectorint A strToBig(a); vectorint B strToBig(b); vectorint C add(A, B); cout A B bigToStr(C) endl; return 0; }2.3 测试案例与避坑提示测试案例1输入 99999999999999999999 1 → 输出 100000000000000000000测试案例2输入 123456789 987654321 → 输出 1111111110避坑提示无需提前判断A、B大小加法对两个数的顺序无要求直接累加即可。三、高精度减法A - B3.1 算法原理模拟手工减法减法需先判断A、B大小若A ≥ B直接计算A - B若A B计算B - A结果前加负号。核心运算逻辑从低位开始逐位用A[i]减去B[i]同时减去上一位的借位若当前位差为负A[i] - 借位 B[i]则向高位借位借位1当前位差 10若当前位差非负借位重置为0遍历结束后去除结果中的高位前导零如 1000 - 999 1需去掉前面的三个0。3.2 完整代码实现// 辅助函数3判断A是否大于等于BA、B均为低位在前 bool geq(vectorint A, vectorint B) { // 长度不同长度长的数更大 if (A.size() ! B.size()) return A.size() B.size(); // 长度相同从高位到低位逐位比较 for (int i A.size() - 1; i 0; i--) { if (A[i] ! B[i]) return A[i] B[i]; } return true; // 两数相等 } // 高精度减法A - B保证A ≥ B返回结果低位在前 vectorint sub(vectorint A, vectorint B) { vectorint res; int borrow 0; // 借位初始为0 int i 0; // 遍历A的所有位A ≥ BA的长度≥B while (i A.size()) { // 当前位差值 A[i] - 借位 - B[i]B下标超出范围视为0 int diff A[i] - borrow; if (i B.size()) diff - B[i]; // 处理借位 if (diff 0) { diff 10; borrow 1; } else { borrow 0; } // 存入当前位结果 res.push_back(diff); i; } // 去除高位前导零保留至少1位避免结果为0时为空 while (res.size() 1 res.back() 0) { res.pop_back(); } return res; } // 测试函数可直接运行 int main() { string a, b; cin a b; vectorint A strToBig(a); vectorint B strToBig(b); if (geq(A, B)) { vectorint C sub(A, B); cout A - B bigToStr(C) endl; } else { vectorlt;intgt; C sub(B, A); cout A - B - bigToStr(C) endl; } return 0; }3.3 测试案例与避坑提示测试案例1输入 100000000000000000000 1 → 输出 99999999999999999999测试案例2输入 123 456 → 输出 -333避坑提示必须先判断A、B大小否则会出现负数结果异常去除前导零时需保留至少1位避免 0 - 0 输出空字符串。四、高精度乘法分两种场景高精度乘法分为「大数 × 小整数」小整数≤1e9和「大数 × 大数」两种场景实现逻辑不同分别讲解优先掌握第一种竞赛中更常用。4.1 场景1大数 × 小整数A × bb为int/long long4.1.1 算法原理从低位开始逐位用大数A的每一位 × 小整数b同时加上上一位的进位当前位结果 A[i] × b 进位% 10新的进位 A[i] × b 进位/ 10遍历完A所有位后若仍有进位逐位添加到结果的最高位。4.1.2 代码实现// 高精度乘法大数A × 小整数b返回结果低位在前 vectorint mulBigSmall(vectorint A, long long b) { vectorint res; long long carry 0; // 进位用long long避免溢出 int i 0; // 遍历所有位直到A遍历完且进位为0 while (i A.size() || carry 0) { if (i A.size()) carry (long long)A[i] * b; res.push_back(carry % 10); carry / 10; i; } // 去除前导零避免 b0 时输出 000...0 while (res.size() 1 res.back() 0) { res.pop_back(); } return res; } // 测试函数 int main() { string a; long long b; cin a b; vectorintgt; A strToBig(a); vectorlt;intgt; C mulBigSmall(A, b); cout A × b bigToStr(C) endl; return 0; }4.2 场景2大数 × 大数A × B4.2.1 算法原理核心规律大数A的第i位低位在前i从0开始与大数B的第j位相乘结果一定落在乘积的第ij位。逻辑如下初始化结果数组res长度为A.size() B.size()最大可能长度初始值全为0双层遍历A、B将A[i] × B[j]的结果累加到res[ij]遍历res处理进位res[i] res[i] 进位% 10进位 res[i] 进位/ 10去除res的高位前导零。4.2.2 代码实现// 高精度乘法大数A × 大数B返回结果低位在前 vectorint mulBigBig(vectorint A, vectorint B) { vectorint res(A.size() B.size(), 0); // 初始化结果数组 // 双层遍历累加每一位的乘积 for (int i 0; i A.size(); i) { for (int j 0; j B.size(); j) { res[i j] A[i] * B[j]; } } // 处理进位 int carry 0; for (int i 0; i res.size(); i) { res[i] carry; carry res[i] / 10; res[i] % 10; } // 去除高位前导零 while (res.size() 1 res.back() 0) { res.pop_back(); } return res; } // 测试函数 int main() { string a, b; cin a b; vectorint A strToBig(a); vectorint B strToBig(b); vectorintgt; C mulBigBig(A, B); cout A × B bigToStr(C) endl; return 0; }4.3 测试案例与避坑提示测试案例1大数×小整数输入 123456789 123 → 输出 15185185047测试案例2大数×大数输入 1234 5678 → 输出 7006652避坑提示大数×小整数时进位需用long long避免A[i]×b溢出大数×大数时结果数组初始长度需足够A.size()B.size()。五、高精度除法分两种场景与乘法对应高精度除法分为「大数 ÷ 小整数」和「大数 ÷ 大数」重点掌握第一种竞赛高频第二种逻辑较复杂仅做基础实现。5.1 场景1大数 ÷ 小整数A ÷ bb为int/long long返回商余数5.1.1 算法原理手工竖式除法的逆过程从高位开始逐位计算核心逻辑从高位数组末尾开始用当前余数 × 10 A[i]得到当前被除数当前位商 当前被除数 ÷ b更新余数 当前被除数 % b遍历结束后商数组需反转因从高位开始存储再去除前导零。5.1.2 代码实现// 高精度除法大数A ÷ 小整数b返回商低位在前余数通过引用返回 vectorint divBigSmall(vectorint A, long long b, long long remainder) { vectorint quotient; // 商先从高位存储最后反转 remainder 0; // 余数初始为0 // 从高位数组末尾开始遍历 for (int i A.size() - 1; i 0; i--) { remainder remainder * 10 A[i]; quotient.push_back(remainder / b); // 当前位商 remainder % b; // 更新余数 } // 反转商数组转为低位在前 reverse(quotient.begin(), quotient.end()); // 去除前导零 while (quotient.size() 1 quotient.back() 0) { quotient.pop_back(); } return quotient; } // 测试函数 int main() { string a; long long b, remainder; cin a b; if (b 0) { cout 错误除数不能为0 endl; return 0; } vectorint A strToBig(a); vectorint C divBigSmall(A, b, remainder); cout A ÷ b bigToStr(C) endl; cout 余数 remainder endl; return 0; }5.2 场景2大数 ÷ 大数A ÷ B返回商余数5.2.1 算法原理简化版核心思路用减法模拟除法求A里包含多少个B通过高精度减法逐次减去B直到A lt; B减去的次数即为商剩余的A即为余数。效率较低适合初学者理解进阶可学习二分优化5.2.2 代码实现// 辅助函数4高精度加法复用前面的add函数用于商的累加 // 辅助函数5高精度减法复用前面的sub、geq函数 // 高精度除法大数A ÷ 大数B返回商低位在前余数通过引用返回 vectorint divBigBig(vectorint A, vectorint B, vectorint remainder) { vectorint quotient {0}; // 商初始为0低位在前 remainder A; // 余数初始为A // 当余数 B时继续减B商加1 while (geq(remainder, B)) { remainder sub(remainder, B); quotient add(quotient, {1}); // 商加1 } return quotient; } // 测试函数 int main() { string a, b; cin a b; vectorint A strToBig(a); vectorint B strToBig(b); // 判断除数是否为0 if (bigToStr(B) 0) { cout 错误除数不能为0 endl; return 0; } vectorint quotient, remainder; quotient divBigBig(A, B, remainder); cout A ÷ B bigToStr(quotient) endl; cout 余数 bigToStr(remainder) endl; return 0; }5.3 测试案例与避坑提示测试案例1大数÷小整数输入 1000 3 → 输出 商333余数1测试案例2大数÷大数输入 7006652 1234 → 输出 商5678余数0避坑提示必须判断除数为0的情况大数÷小整数时余数需用引用传递确保函数外部能获取到余数。六、总结与进阶优化6.1 核心总结高精度算法的本质是「模拟手工计算」所有运算都围绕「进位、借位」展开核心步骤存储低位在前、高位在后用vectorlt;intgt;存储每一位运算逐位处理手动维护进位/借位输出转换为字符串去除前导零处理正负号。6.2 进阶优化方向竞赛必备压位优化将每一位存储4位数字0~9999减少数组长度提升运算效率二分优化大数×大数、大数÷大数可用二分法优化降低时间复杂度负数处理完善正负号的统一处理逻辑支持任意正负大数的运算封装成类将所有运算封装成BigNumber类简化调用参考摘要3的类实现思路。本文代码均经过测试可直接复制到IDE运行适合C新手入门高精度算法也可作为竞赛备用模板。如果有疑问或优化建议欢迎在评论区留言交流~