【自种树自乘凉】JS 实现两个大数相加?

1,683 阅读2分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

理论:

当有两个整数 a 和 b ,在通常情况下我们有 “+” 运算符对其进行相加运算:

let sum = a + b;

但是 JS 在存放整数的时候是有一个安全范围的,一旦数字超过这个范围便会损失精度

我们不能拿精度损失的数字进行运行,因为运算结果一样是会损失精度的。

所以,我们要用字符串来表示数据!(确保不会丢失精度)

JS 中整数的最大安全范围可以查到是:9007199254740991

假如我们要进行 9007199254740991 + 1234567899999999999

第一个数字刚好在安全范围以内,第二个数字已经远远超出安全范围了。

我们现在先到谷歌浏览器下跑一下这两个数字加法运算的结果:1243575099254741000

这个结果显然是不对的,我们大致心算一下尾数部分就知道不可能是 000 结尾。

所以有了下面这个用字符串来表示大数并进行加法运算的初步方案。

正文:

我们要先准备两个字符串变量和一个方法:

let a = "9007199254740991";
let b = "1234567899999999999";

function add(a ,b){
   //...
}

然后将字符串长度对齐:

let a = "9007199254740991";
let b = "1234567899999999999";

function add(a ,b) {
   // 取两个数字的最大长度
   let maxLength = Math.max(a.length, b.length);
   // 用 0 去补齐长度
   a = a.padStart(maxLength , 0); // "0009007199254740991"
   b = b.padStart(maxLength , 0); // "1234567899999999999"
}

然后从个位开始相加:

let a = "9007199254740991";
let b = "1234567899999999999";

function add(a ,b) {
   // 取两个数字的最大长度
   let maxLength = Math.max(a.length, b.length);
   // 用 0 去补齐长度
   a = a.padStart(maxLength , 0); // "0009007199254740991"
   b = b.padStart(maxLength , 0); // "1234567899999999999"
   // 定义加法过程中需要用到的变量
   let t = 0;
   let f = 0;   // "进位"
   let sum = "";
   for(let i = maxLength-1; i >= 0; i--){
      t = parseInt(a[i]) + parseInt(b[i]) + f;
      f = Math.floor(t / 10);
      sum = t % 10 + sum;
   }
   if(f == 1){
      sum = "1" + sum;
   }
   return sum;
}

运行:

add(a ,b);

结果为:1243575099254740990

End