大整数相加
用字符串模拟竖式加法,处理超出 Number 精度的大正整数求和,常见前端面试手写题。
#algorithm #interview
大整数相加
JavaScript 的 Number 基于 IEEE 754 双精度浮点,安全整数范围是 -(2^53 - 1) 到 2^53 - 1(即 Number.MAX_SAFE_INTEGER)。当两个「大正整数」字符串相加时,不能直接用 + 或 Number() 转换,否则会丢失精度。
这道题的核心思路是:模拟小学竖式加法——从低位到高位逐位相加,维护进位。
思路
- 将两个操作数转为字符串(或本来就是字符串)
- 从最后一位(个位)向前遍历
- 对应位数字相加,再加上进位
carry - 当前位结果 =
sum % 10,新进位 =Math.floor(sum / 10) - 遍历结束后若仍有进位,需要补一位
- 将结果数组反转(或从高位拼接)得到最终字符串
实现一:数组收集后反转
从字符串末尾双指针向前扫,结果先 push 到数组,最后 reverse().join("")。
addBigIntegers
javascriptfunction addBigIntegers(a, b) {
const strA = String(a);
const strB = String(b);
let i = strA.length - 1;
let j = strB.length - 1;
let carry = 0;
const result = [];
while (i >= 0 || j >= 0 || carry > 0) {
const digitA = i >= 0 ? Number(strA[i--]) : 0;
const digitB = j >= 0 ? Number(strB[j--]) : 0;
const sum = digitA + digitB + carry;
result.push(sum % 10);
carry = Math.floor(sum / 10);
}
return result.reverse().join("");
}注意 while 条件里的 carry > 0:最高位相加后若产生进位(如 999 + 1),循环需要多跑一轮。
实现二:左对齐补零,高位拼接
另一种写法是先去掉前导零、用 padStart 对齐长度,再从右向左遍历,把每位结果拼到字符串前面。
addBigIntegers(对齐版)
javascriptfunction addBigIntegers(a, b) {
a = String(a).replace(/^0+/, "") || "0";
b = String(b).replace(/^0+/, "") || "0";
const lth = Math.max(a.length, b.length);
a = a.padStart(lth, "0");
b = b.padStart(lth, "0");
let carry = 0;
let result = "";
for (let i = lth - 1; i >= 0; i--) {
const sum = Number(a[i]) + Number(b[i]) + carry;
carry = Math.floor(sum / 10);
result = String(sum % 10) + result;
}
if (carry > 0) result = String(carry) + result;
return result;
}相比实现一,这版额外处理了前导零("0123" + "456" → "579"),对小整数也适用。
测试用例
addBigIntegers("999999999999999999999", "1")
// → "1000000000000000000000"
addBigIntegers("12345678901234567890", "98765432109876543210")
// → "111111111011111111100"
addBigIntegers(123, 456)
// → "579"
addBigIntegers("0123", "456")
// → "579"
复杂度与边界
| 项目 | 说明 |
|---|---|
| 时间复杂度 | O(max(m, n)),m、n 为两数位数 |
| 空间复杂度 | O(max(m, n)),存放结果 |
| 负数 | 本题通常只考大正整数;若需支持负数,要先处理符号与绝对值大小比较 |
| 小数 | 需先对齐小数点,再分别处理整数与小数部分 |
延伸:BigInt
现代环境可直接用 BigInt:
String(BigInt("999999999999999999999") + BigInt("1"))
// → "1000000000000000000000"
面试手写时仍建议掌握字符串模拟竖式加法——考察的是对进位、边界和字符串操作的理解,而非 API 记忆。
小结
- 大整数相加不能依赖
Number,应逐位模拟竖式加法 - 双指针从末尾向前扫,或
padStart对齐后从右向左拼结果 - 循环条件要覆盖「最后一位仍有进位」的情况
- 对齐版实现还能统一处理前导零与小整数输入