亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript大數(shù)相加相乘的實現(xiàn)方法實例

 更新時間:2020年10月18日 15:31:36   作者:Clloz  
這篇文章主要給大家介紹了關(guān)于JavaScript大數(shù)相加相乘的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

JavaScript 中的最大安全整數(shù)是 2 ^{53} – 1 ,即 9007199254740991,當我們進行超出這個范圍的數(shù)值計算的時候就無法得到精確的值,而是一個近似值,比如我們計算 9007199254740991 + 10 得到的結(jié)果是 9007199254741000。本文講一下如何利用字符串在 JavaScript 中實現(xiàn)大數(shù)相加相乘。

相加

用字符串實現(xiàn)相加相乘基本思路就是按照我們在紙上進行豎式運算一樣。對于加法,我們需要將兩個數(shù) num1 和 num2 上下對齊,然后從個位開始計算兩個數(shù)對應(yīng)位的和,循環(huán)到最高位,將每一次運算的結(jié)果保存到一個數(shù)組 result 中去,最終用 Array.prototype.join() 方法還原成一個數(shù)組。

這里為了保持循環(huán)的正常進行,我們需要保證兩個字符串位數(shù)相等,所以我們要用 String.prototpye.padStart() 方法將位數(shù)比較小的那一個字符串的前面用 '0' 補齊。

按位相加有個問題就是進位如何保存,我的思路是這樣的。當我們相加 num1[i] 和 num2[i] 的時候,得到的最多是一個兩位數(shù),它將影響 result 的兩位,即當前的 result[0] 位置和即將 unshift 到 result 中的一位。當前的 result[0] 位置的數(shù)就是計算 [i -1] 是得到的數(shù)的高位(即進位),我們將我們計算的值加上進位,得到的數(shù)在分成兩位分別放到 result 中。

所以總結(jié)一下就是我們計算 num1[i] + num2[i] 得到一個兩位數(shù),這個兩位數(shù)要先和 num1[i-1] + num2[i-1] 的結(jié)果的進位(即 result[0] 相加,然后在分成 high 和 low 兩位,將 result[0] 的值用 low 位替換,然后將 high 位 unshift 到 result 最前面??梢詤⒖枷聢D理解。

所以我們每次計算都是確定一位和下一位的進位。最后代碼如下:

let add = function (num1, num2) {
 if (isNaN(num1) || isNaN(num2)) return '';
 if (num1 === '0' || num2 === '0') return (num1 === '0' ? num2 : num1);

 let len = Math.max(num1.length, num2.length);
 num1 = num1.padStart(len, '0');
 num2 = num2.padStart(len, '0');

 let result = [];

 for (let i = len - 1; i >= 0; i--) {
  let sum = Number(num1[i]) + Number(num2[i]) + (result[0] || 0);
  let low = sum % 10;
  let high = Math.floor(sum / 10);

  result[0] = low;
  result.unshift(high);
 }
 return result.join('');
}

console.log(add('10', '9007199254740991')) //09007199254741001

代碼中我們加了兩個判斷,判斷兩個參數(shù)是否是合法數(shù)字格式,以及如果一個數(shù)是 '0' 則直接返回另一個數(shù)。

相乘

相乘的邏輯要比相加復(fù)雜一點,但是總體思路還是根據(jù)豎式來實現(xiàn)算法,我畫了一張圖,我們借助圖來說明。

相乘是一個兩層循環(huán),我們要循環(huán)一個數(shù)的位,每一位再與另一個數(shù)循環(huán)的每一位相乘。我們每次相乘的結(jié)果最多是一個兩位數(shù)。但是與相加不同的是,相加的 high 每次都是 unshift 進去即可,而相乘的高位也要與 result 的位進行運算。

我們來看一看相乘的規(guī)律,當我們用 num1[i] * num2[j] 的時候,可能得到兩位數(shù),也可能得到一位數(shù),我們都統(tǒng)一算作兩位數(shù),高位沒有的就用 0 補齊,那么最后我們得到的結(jié)果將是一個 i + j 位的數(shù)(開頭可能存在補齊的 0)。而我們每次計算 num1[i] * num2[j] 的結(jié)果影響到的都是 result 中的 i + j 和 i + j + 1 位。

和加法中邏輯一樣,我們將 num1[i] * num2[j] 的結(jié)果和 result[i + j + 1] 相加,得到的結(jié)果分為 low 和 high 分別存入 reslut 的 [i + j +1] 和 [i +j] 中。但是這里要注意,和加法不同,加法的高位直接存入就可以,我們這里的 high 對應(yīng)的 result[i + j] 可能已經(jīng)有值了,我們需要將已經(jīng)存在的值加上。

high 和 result[i +j] 的相加可能存在進位怎么辦呢,看上圖中右邊的當前 result 值中我們可以看到有些位存了不止一位數(shù),我們將 high + result[i +j] 的值直接連進位一起保存到 result[i + j] 中。為什么能這樣做呢,因為下次計算 num1[i] * num2[j - 1] 的時候(注意我們是從后往前遍歷),會把 result[i + j]和 low 相加,進位自然能被處理,這也是這個算法比較重要的地方。

最后的代碼:

let multiply = function (num1, num2) {
  if (isNaN(num1) || isNaN(num2)) return '';
  if (num1 === '0' || num2 === '0') return '0';

  let l1 = num1.length,
    l2 = num2.length;

  let result = [];

  for (let i = l1 -1; i >= 0; i--) {
    for (let j = l2 - 1; j >= 0; j--) {
      let index1 = i + j;
      let index2 = i + j + 1;

      let product = num1[i] * num2[j] + (result[index2] || 0);
      result[index2] = product % 10;
      result[index1] = Math.floor(product / 10) + (result[index1] || 0);
    }
  }
  return result.join('').replace(/^0+/, '');
}

console.log(multiply('123', '234')) //28782

代碼中加了兩個判斷:是否是合法數(shù)字,如果有一個值為 0 則直接返回 0。注意最后要判斷得到的結(jié)果是否開頭有 0,如果有則要去掉,這里用的正則表達式。

總結(jié)

到此這篇關(guān)于JavaScript大數(shù)相加相乘的實現(xiàn)方法的文章就介紹到這了,更多相關(guān)JavaScript大數(shù)相加相乘內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論