因为C++原生整型位宽固定,int和long long无法存储超长数字,必须用字符串模拟手工加法:倒序逐位相加、处理进位,最后反转结果。

为什么不能直接用 int 或 long long 做大数相加
因为 C++ 原生整型有固定位宽,int 通常最多存 10 位十进制数,long long 也只撑到约 19 位。一旦输入超过这个长度(比如 100 位的数字字符串),直接转换会溢出或截断,结果完全错误。
所以必须把数字当字符串读入,逐位模拟手工加法——从个位开始,带进位相加,结果存进新字符串。
- 输入一定是非负整数字符串(如
"999"、"12345678901234567890") - 不支持负号或小数点;若需处理负数,得先解析符号再分情况调用加/减逻辑
- 两个字符串长度可能差异很大,不能假设等长
如何逐位模拟加法并处理进位
核心是倒序遍历两个字符串,用 carry 记录当前进位(初始为 0),每次取对应位的数字(越界则按 0 处理),计算 sum = digit1 + digit2 + carry,然后 carry = sum / 10,当前位结果为 sum % 10。
最后别忘了把最高位的 carry(可能是 1)追加进去。
立即学习“C++免费学习笔记(深入)”;
网趣购物系统静态版支持网站一键静态生成,采用动态进度条模式生成静态,生成过程更加清晰明确,商品管理上增加淘宝数据包导入功能,与淘宝数据同步更新!采用领先的AJAX+XML相融技术,速度更快更高效!系统进行了大量的实用性更新,如优化核心算法、增加商品图片批量上传、谷歌地图浏览插入等,静态版独特的生成算法技术使静态生成过程可随意掌控,从而可以大大减轻服务器的负担,结合多种强大的SEO优化方式于一体,使
示例关键片段:
string addStrings(string num1, string num2) {
string res;
int i = num1.size() - 1, j = num2.size() - 1, carry = 0;
while (i >= 0 || j >= 0 || carry) {
int d1 = (i >= 0) ? num1[i--] - '0' : 0;
int d2 = (j >= 0) ? num2[j--] - '0' : 0;
int sum = d1 + d2 + carry;
carry = sum / 10;
res.push_back('0' + (sum % 10));
}
reverse(res.begin(), res.end());
return res;
}
为什么必须反转结果字符串
因为是从个位开始算的,每次 push_back 得到的是“低位在前”的顺序(比如算 "123"+"45",先得到个位 '8',再十位 '6',再百位 '1',拼出来是 "861"),必须 reverse 才能变成正确顺序 "168"。
- 不反转会导致结果完全颠倒,这是新手最常漏掉的一步
- 也可以改用
res.insert(res.begin(), '0' + (sum % 10))避免反转,但每次插入头是 O(n),整体变慢 - 用
vector替代string中间存储,最后构造string,性能更稳
边界情况和易错点
实际写的时候,光逻辑对还不够,容易在细节上翻车:
- 空字符串输入:虽然题目通常保证非空,但加一句
if (num1.empty()) return num2;更健壮 - 字符转数字写成
num1[i] - '0',不是- 0或- '1';ASCII 差值必须准确 -
i--和j--要放在三元表达式里,不能写在 while 循环末尾——否则某次越界后还会多减一次 - 循环条件是
i >= 0 || j >= 0 || carry,不是只判i和j;否则最后进位 1 会被丢掉
高精度加法真正难的不是算法本身,而是这些下标、边界、字符/数字转换的细节堆叠起来,一不小心就段错误或结果错一位。写完务必用 "999"+"1"、"0"+"0"、"123"+"4567" 这类极端样例过一遍。










