JS實現大數相加大數相乘示例詳解

JS大數相加、大數相乘

JavaScript 隻有一種數字類型,可以使用也可以不使用小數點來書寫數字。

JavaScript 中,數字不分為整數類型和浮點數類型,所有的數字都是浮點數類型JavaScript 采用 IEEE754 標準定義的 64 位浮點格式表示數字,此格式用 64 位存儲數值。其中 0~51存儲數字片段,52~62存儲指數,63 位存儲符號。

來看看 JavaScript 中數字的最大值最小值

console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324

註:

這裡的最大值指的是字面意思上的最大值;

最小值則指的是正數情況下小數點後能表示的最小值。

一、實現兩個大數相加

思路:

大數可能會超出 JavaScript數字類型范圍,超出後結果損失精度,所以可以用字符串的方式來存儲大數。

題解:

let a = "9876543210123456789000000000123";
let b = "1234567898765432100000012345678901";
function add(str1, str2) {
  // 獲取兩個數字的最大長度
  let maxLength = Math.max(str1.length, str2.length);
  // 用0補齊長度,讓它們兩個長度相同
  str1 = str1.padStart(maxLength, 0); // "0009876543210123456789000000000123"
  str2 = str2.padStart(maxLength, 0); // "1234567898765432100000012345678901"
  let temp = 0; // 每個位置相加之和
  let flag = 0; // 進位:相加之和如果大於等於10,則需要進位
  let result = "";
  for(let i=maxLength-1; i>=0; i--) {
    // 獲取當前位置的相加之和:字符串1 + 字符串2 + 進位數字
    temp = parseInt(str1[i]) + parseInt(str2[i]) + flag;
    // 獲取下一個進位
    flag = Math.floor(temp/10);
    // 拼接結果字符串
    result = temp%10 + result;
  }
  if(flag === 1) {
    // 如果遍歷完成後,flag還剩1,說明兩數相加之後多瞭一位,類似於:95 + 10 = 105
    result = "1" + result;
  }
  return result;
}

二、實現兩個大數相乘

給定兩個以字符串形式表示的非負整數 num1num2,返回 num1num2 的乘積,它們的乘積也表示為字符串形式。

思路:

  • 首先,兩個多位數相乘,我們可以分解成其中一個多位數另一個多位數的每一位相乘
    • 這裡利用的思路和上面的大數相加一致
  • 得到其每一位相乘的結果後,在其結果後面補齊相應的0,並將其放入結果數組中
  • 最後,用上述大數相加的函數,對結果數組進行累加,即可得到最終的相乘字符串瞭。
  • 需要註意的點是相乘的兩數其中之一可能是0,所以最後一步需要將左側的0(除瞭最右邊的一位)全部去掉
function multiply(str1, str2) {
  let result = "";
  const multiplyArr = [];
  let count = 0; // 當前位數(從個位開始)
  // 用位數少的每一位去乘位數多的,這樣需要的存儲空間更小,運算速度更快
  if(str1.length < str2.length) {
    [str1, str2] = [str2, str1];
  }
  // 循環用第二個數的每一位乘以第一個數
  for(let i=str2.length-1; i>=0; i--) {
    let multiplyItem = manyMultiplyOne(str1, str2[i]); // 獲取多位數乘單位數的結果
    multiplyArr[count] = multiplyItem.padEnd(multiplyItem.length + count, "0"); // 進行補0操作
    count++;
  }
  // 接下來,將multiplyArr中的每一項累加,就能得到最終的結果瞭
  result = multiplyArr[0] // 從第一個開始累加
  for(let i=1; i<multiplyArr.length; i++) {
    result = add(result, multiplyArr[i]);
  }
  // 去除末尾以外的前置0
  result = removeLeftZero(result);
  return result;
}
/**
 * 多位數乘單個數
 */
function manyMultiplyOne(many, one) {
  let temp = 0; // 每個位置相乘的結果
  let flag = 0; // 進位數
  let result = "";
  // 進行每一位的乘法運算,並進行進位操作(從後往前操作,代表從最小位置開始:個十百千萬)
  for(let i=many.length-1; i>=0; i--) {
    temp = many[i] * one + flag; // 獲取當前項的乘積
    flag = Math.floor(temp/10); // 獲取進位數
    result = temp%10 + result;
  }
  // 最後,如果進位還要剩下,則將進位放在最前面
  if(flag !== 0) {
    result = flag + result;
  }
  return result;
}
// 兩數相加,用的上面介紹的函數
function add(str1, str2) {
  // 獲取兩個數字的最大長度
  let maxLength = Math.max(str1.length, str2.length);
  // 用0補齊長度,讓它們兩個長度相同
  str1 = str1.padStart(maxLength, 0); // "0009876543210123456789000000000123"
  str2 = str2.padStart(maxLength, 0); // "1234567898765432100000012345678901"
  let temp = 0; // 每個位置相加之和
  let flag = 0; // 進位:相加之和如果大於等於10,則需要進位
  let result = "";
  for(let i=maxLength-1; i>=0; i--) {
    // 獲取當前位置的相加之和:字符串1 + 字符串2 + 進位數字
    temp = parseInt(str1[i]) + parseInt(str2[i]) + flag;
    // 獲取下一個進位
    flag = Math.floor(temp/10);
    // 拼接結果字符串
    result = temp%10 + result;
  }
  if(flag === 1) {
    // 如果遍歷完成後,flag還剩1,說明兩數相加之後多瞭一位,類似於:95 + 10 = 105
    result = "1" + result;
  }
  return result;
}
function removeLeftZero(str) {
  let count = 0; // 計算從頭部開始,有幾個0
  for(let i=0; i<str.length; i++) {
    if(str[i] === "0" && i < str.length - 1) {
      count++;
    } else {
      break;
    }
  }
  return str.substr(count, str.length);
}

以上就是JS實現大數相加大數相乘示例詳解的詳細內容,更多關於JS大數相加相乘的資料請關註WalkonNet其它相關文章!

推薦閱讀: