javascript处理大数需绕过number精度限制,核心是用字符串模拟竖式加/乘法或使用bigint。字符串法需对齐、逐位计算并处理进位;bigint更简洁但不兼容number和json。

JavaScript 中处理大数相加和相乘,核心是避免原生 Number 类型的精度限制(最大安全整数为 Number.MAX_SAFE_INTEGER = 9007199254740991)。超过该值后,整数运算会出现精度丢失。因此,**必须脱离浮点数运算,用字符串或数组模拟手工竖式计算逻辑**。
用字符串模拟竖式加法
将两个大数转为字符串,从末位开始逐位相加,维护进位,拼接结果:
- 先对齐长度(短的前面补 "0"),方便统一索引遍历
- 从右往左遍历,按字符转数字相加 + 进位,取模得当前位,除 10 取整更新进位
- 循环结束后若仍有进位,需额外追加到结果开头
- 注意去除前导零(但结果为 "0" 时不能全删)
示例(加法):
function addBigNumbers(a, b) {let i = a.length - 1, j = b.length - 1;
let carry = 0;
let res = '';
while (i >= 0 || j >= 0 || carry) {
const x = i >= 0 ? +a[i--] : 0;
const y = j >= 0 ? +b[j--] : 0;
const sum = x + y + carry;
res = (sum % 10) + res;
carry = Math.floor(sum / 10);
}
return res;
}
用字符串模拟竖式乘法
乘法比加法复杂,本质是「多位乘多位 → 拆成多个单数×多位 → 错位相加」。常用优化方式是直接申请长度为 a.length + b.length 的结果数组,按位累加:
- 外层遍历被乘数每一位(i),内层遍历乘数每一位(j)
- 两数在位置 i 和 j 相乘,结果影响结果数组中
i + j + 1(个位)和i + j(进位)两个位置 - 先全部累加完,再统一从低位向高位处理进位
- 最后转字符串,跳过前导零
示例(乘法核心逻辑):
if (a === '0' || b === '0') return '0';
const res = new Array(a.length + b.length).fill(0);
for (let i = a.length - 1; i >= 0; i--) {
for (let j = b.length - 1; j >= 0; j--) {
const mul = (+a[i]) * (+b[j]);
const p1 = i + j, p2 = i + j + 1;
const sum = mul + res[p2];
res[p2] = sum % 10;
res[p1] += Math.floor(sum / 10);
}
}
return res.join('').replace(/^0+/, '') || '0';
}
直接使用 BigInt(推荐用于现代环境)
ES2020 引入了 BigInt 类型,可安全表示任意精度整数(后缀 n 或 BigInt() 构造):
- 支持
+、*、-、**等运算符,语义与Number一致 - 注意:
BigInt不能与Number混合运算(会报错),必须显式转换 - JSON 不支持
BigInt,序列化需自行处理
示例:
const a = 123456789012345678901234567890n;const b = 987654321098765432109876543210n;
console.log(a + b); // 1111111110111111111011111111100n
console.log(a * b); // ……(精确结果)
注意事项与边界情况
手写字符串算法时需特别留意:
- 输入可能含负号:先提取符号,对绝对值计算,再合并结果符号
- 输入可能为空、全零、带空格或非法字符:建议前置校验与清洗
- 乘法中,一个数为 "0" 要提前返回,避免冗余计算
- 性能敏感场景慎用手写(尤其超长数),
BigInt在 V8 等引擎中已高度优化
不复杂但容易忽略。











