实现一个add方法完成两个大数相加
使用字符串模拟竖式加法,解决JavaScript中超出安全整数范围的大数相加问题
问题
在JavaScript中,当数字超过 Number.MAX_SAFE_INTEGER(2^53 - 1)时,会失去精度。例如:
console.log(9007199254740991 + 2); // 9007199254740992 (错误)
我们需要实现一个 add 方法,能够正确处理任意大的整数相加,返回准确的结果字符串。
解答
/**
* 大数相加
* @param {string} num1 - 第一个加数
* @param {string} num2 - 第二个加数
* @return {string} - 相加结果
*/
function add(num1, num2) {
// 转换为字符串并去除空格
num1 = String(num1).trim();
num2 = String(num2).trim();
// 获取两个数的长度
let i = num1.length - 1;
let j = num2.length - 1;
// 进位标志
let carry = 0;
// 结果数组
let result = [];
// 从个位开始逐位相加
while (i >= 0 || j >= 0 || carry > 0) {
// 获取当前位的数字,如果已经遍历完则为0
const digit1 = i >= 0 ? parseInt(num1[i]) : 0;
const digit2 = j >= 0 ? parseInt(num2[j]) : 0;
// 当前位相加(包括进位)
const sum = digit1 + digit2 + carry;
// 计算新的进位
carry = Math.floor(sum / 10);
// 当前位的结果
result.unshift(sum % 10);
// 移动指针
i--;
j--;
}
return result.join('');
}
使用示例
// 示例1:普通大数相加
console.log(add('123456789', '987654321'));
// 输出: "1111111110"
// 示例2:超出安全整数范围
console.log(add('9007199254740991', '9007199254740991'));
// 输出: "18014398509481982"
// 示例3:不同长度的数字
console.log(add('999', '1'));
// 输出: "1000"
// 示例4:带有前导零的情况
console.log(add('00123', '00456'));
// 输出: "579"
// 示例5:极大的数字
console.log(add(
'123456789012345678901234567890',
'987654321098765432109876543210'
));
// 输出: "1111111110111111111011111111100"
关键点
-
字符串处理:将数字转换为字符串进行处理,避免精度丢失
-
逆序遍历:从个位(字符串末尾)开始向高位遍历,模拟手工竖式加法
-
进位处理:使用
carry变量记录进位,每次相加后更新进位值 -
补零对齐:当某个数字已遍历完时,用 0 补充,确保计算完整
-
循环条件:
while (i >= 0 || j >= 0 || carry > 0)确保处理完所有位和最后的进位 -
结果构建:使用
unshift将每位结果添加到数组开头,最后join成字符串 -
时间复杂度:O(max(m, n)),其中 m 和 n 分别是两个数字的长度
-
空间复杂度:O(max(m, n)),用于存储结果数组
目录