乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      JavaScript 進制轉(zhuǎn)換&位運算,了解一下?

       小世界的野孩子 2020-08-04

      前言

      在一般的代碼中很少會接觸到進制和位運算,但這不代表我們可以不去學習它。作為一位編程人員,這些都是基礎知識。如果你沒有學過這方面的知識,也不要慌,接下來的知識并不會很難。本文你將會學習到:

      • 進制轉(zhuǎn)換
      • 按位操作符
      • Javascript進制轉(zhuǎn)換
      • 手動實現(xiàn)進制轉(zhuǎn)換

      進制轉(zhuǎn)換

      以下使用常見的十進制和二進制轉(zhuǎn)換作為例子,其他進制的轉(zhuǎn)換也是大同小異,感興趣可以自己琢磨下。

      十進制轉(zhuǎn)二進制

      根據(jù) “逢十進一” 的法則進行計數(shù)時,每十個相同的單位組成一個和它相鄰的較高的單位,這種計數(shù)法叫做十進制計數(shù)法,簡稱十進制。這種是我們最常用的計數(shù)法。

      整數(shù)

      整數(shù)使用 “除二取余,逆序排列” 來轉(zhuǎn)換為二進制,下面是18轉(zhuǎn)換為二進制的例子:

      // 除二取余
      18 / 2 = 9...0
       9 / 2 = 4...1
       4 / 2 = 2...0
       2 / 2 = 1...0
       1 / 2 = 0...1
      
      // 倒序排列
      10010
      

      就這么簡單,將得出的余數(shù)逆序排列,即可得出18的二進制表示

      小數(shù)

      小數(shù)使用的是 “乘二取整,順序排列”,由于方法不同需要分開計算。下面是16.125轉(zhuǎn)為二進制的例子:

      16 / 2 = 8...0
       8 / 2 = 4...0
       4 / 2 = 2...0
       2 / 2 = 1...0
       1 / 2 = 0...1
      
      0.125 * 2 = 0.25
      0.25 * 2  = 0.5
      0.5  * 2  = 1
      
      10000.001
      

      將小數(shù)相乘的結(jié)果,取結(jié)果的整數(shù)順序排列,得出小數(shù)位的二進制表示

      二進制轉(zhuǎn)十進制

      根據(jù) “逢二進一 ” 的法則進行計數(shù)時,每兩個相同的單位組成一個和它相鄰的較高的單位,這種計數(shù)法叫做二進制計數(shù) 法,簡稱二進制。用二進制計數(shù)時,只需用兩個獨立的符號“0”和“1” 來表示。

      整數(shù)

      整數(shù)使用 “按權(quán)相加” 法,即二進制數(shù)首先寫成加權(quán)系數(shù)展開式,然后按十進制加法規(guī)則求和。下面是101010轉(zhuǎn)換位十進制的例子:

      2^5 2^4 2^3 2^2 2^1 2^0   
       1   0   1   0   1   0
      ------------------------
      32 + 0 + 8 + 0 + 2 + 0 = 42
      

      上面從右數(shù)依次是2的0次方,2的1次方,2的2次方... , 只取位數(shù)為1的結(jié)果,將它們相加就可以得到十進制。

      小數(shù)

      10110.11轉(zhuǎn)十進制:

      2^4 2^3 2^2 2^1 2^0 2^-1 2^-2
       1   0   1   1   0 .  1   1
      -------------------------------
      16 + 0 + 4 + 2 + 0 + 0.5 + 0.25 = 22.75
      

      按位操作符

      按位操作符(Bitwise operators) 將其操作數(shù)(operands)當作32位的比特序列(由0和1組成),前 31 位表示整數(shù)的數(shù)值,第 32 位表示整數(shù)的符號,0 表示正數(shù),1 表示負數(shù)。例如,十進制數(shù)18,用二進制表示則為10010。按位操作符操作數(shù)字的二進制形式,但是返回值依然是標準的JavaScript數(shù)值。

      按位與( AND)

      對于每一個比特位,只有兩個操作數(shù)相應的比特位都是1時,結(jié)果才為1,否則為0。

      用法: a & b 。

           9 (base 10) = 00000000000000000000000000001001 (base 2)
          14 (base 10) = 00000000000000000000000000001110 (base 2)
                         --------------------------------
      14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
      

      在判斷一個數(shù)字奇偶時,可以使用 a & 1

      function assert(n) {
          return n & 1 ? "奇數(shù)" : "偶數(shù)"
      }
      assert(3) // 奇數(shù)
      

      因為奇數(shù)的二進制最后一位是1,而1的二進制最后一位也是1,通過 & 操作符得出結(jié)果為1

      按位或(OR)

      對于每一個比特位,當兩個操作數(shù)相應的比特位至少有一個1時,結(jié)果為1,否則為0。

      用法: a | b

           9 (base 10) = 00000000000000000000000000001001 (base 2)
          14 (base 10) = 00000000000000000000000000001110 (base 2)
                         --------------------------------
      14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
      

      將浮點數(shù)向下取整轉(zhuǎn)為整數(shù),可以使用 a | 0

      12.1 | 0 // 12
      12.9 | 0 // 12
      

      按位異或(XOR)

      對于每一個比特位,當兩個操作數(shù)相應的比特位有且只有一個1時,結(jié)果為1,否則為0。

      用法: a ^ b

           9 (base 10) = 00000000000000000000000000001001 (base 2)
          14 (base 10) = 00000000000000000000000000001110 (base 2)
                         --------------------------------
      14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
      

      按位非(NOT)

      反轉(zhuǎn)操作數(shù)的比特位,即0變成1,1變成0。

      用法: ~ a

       9 (base 10) = 00000000000000000000000000001001 (base 2)
                     --------------------------------
      ~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
      

      通過兩次反轉(zhuǎn)操作,可將浮點數(shù)向下取整轉(zhuǎn)為整數(shù)

      ~~16.125 // 16
      ~~16.725 // 16
      

      左移(Left shift)

      將 a 的二進制形式向左移 b (< 32) 比特位,右邊用0填充。

      用法: a << b

           9 (base 10): 00000000000000000000000000001001 (base 2)
                        --------------------------------
      9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
      

      左移一位相當于在原數(shù)字基礎上乘2,利用這一特點,實現(xiàn)2的n次方:

      function power(n) {
          return 1 << n
      }
      power(3) // 8
      

      有符號右移

      將 a 的二進制表示向右移 b (< 32) 位,丟棄被移出的位。

      用法: a >> b

           9 (base 10): 00000000000000000000000000001001 (base 2)
                        --------------------------------
      9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
      

      相比之下, -9 >> 2 得到 -3,因為符號被保留了。

           -9 (base 10): 11111111111111111111111111110111 (base 2)
                         --------------------------------
      -9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
      

      與左移相反,右移一位在原數(shù)字基礎上除以2

      64 >> 1 // 32
      

      無符號右移

      將 a 的二進制表示向右移 b (< 32) 位,丟棄被移出的位,并使用 0 在左側(cè)填充。

      用法: a >>> b

      在非負數(shù)來說, 9 >>>2 9 >> 2 都是一樣的結(jié)果

            9 (base 10): 00000000000000000000000000001001 (base 2)
                         --------------------------------
      9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
      

      而對于負數(shù)來說,結(jié)果就大有不同了,因為 >>> 不保留符號,當負數(shù)無符號右移時,會使用0填充

            -9 (base 10): 11111111111111111111111111110111 (base 2)
                          --------------------------------
      -9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
      

      可以使用無符號右移來判斷一個數(shù)的正負

      function isPos(n) {
          return (n === (n >>> 0)) ? true : false;
      }
      
      isPos(-1); // false
      isPos(1); // true
      

      雖然 -1 >>> 0 不會發(fā)生右移,但 -1 的二進制碼已經(jīng)變成了正數(shù)的二進制碼, -1 >>> 0 結(jié)果為4294967295

      Javascript進制轉(zhuǎn)換

      toString

      toString 常用于將一個變量轉(zhuǎn)為字符串,或是判斷一個變量的類型,例如:

      let arr = []
      Object.prototype.toString.call(arr) // [object Array]
      

      你應該沒想過 toString 可以用于進制轉(zhuǎn)換,請看下面例子:

      (18).toString(2)  // 10010(base 2)
      (18).toString(8)  // 22 (base 8)
      (18).toString(16) // 12 (base 16)
      

      參數(shù)規(guī)定表示數(shù)字的基數(shù),是 2 ~ 36 之間的整數(shù),若省略該參數(shù),則使用基數(shù) 10。該參數(shù)可以理解為轉(zhuǎn)換后的進制表示。

      parseInt

      parseInt 常用于數(shù)字取整,它同樣可以傳入?yún)?shù)用于進制轉(zhuǎn)換,請看下面例子:

      parseInt(10010, 2) // 18 (base 10)
      parseInt(22, 8)    // 18 (base 10)
      parseInt(12, 16)   // 18 (base 10)
      

      第二個參數(shù)表示要解析的數(shù)字的基數(shù),該值介于 2 ~ 36 之間。如果省略該參數(shù)或其值為 0,則數(shù)字將以 10 為基礎來解析。如果該參數(shù)小于 2 或者大于 36,則 parseInt 將返回 NaN。

      記得有道面試題是這樣的:

      // 問:返回的結(jié)果
      [1, 2, 3].map(paseInt)
      

      接下來,我們來一步一步的看下過程發(fā)生了什么?

      parseInt(1, 0) // 基數(shù)為 0 時,以 10 為基數(shù)進行解析,結(jié)果為 1
      parseInt(2, 1) // 基數(shù)不符合 2 ~ 36 的范圍,結(jié)果為 NaN
      parseInt(3, 2) // 這里以 2 為基數(shù)進行解析,但 3 很明顯不是一個二進制表示,故結(jié)果為 NaN
      
      //題目結(jié)果為
      [1, NaN, NaN]
      

      手動實現(xiàn)進制轉(zhuǎn)換

      雖然 JavaScript 為我們內(nèi)置了進制轉(zhuǎn)換的函數(shù),但手動實現(xiàn)進制轉(zhuǎn)換有利于我們理解過程,提高邏輯能力。對于初學者來說也是一個很不錯的練習例子。以下只簡單實現(xiàn)非負整數(shù)的轉(zhuǎn)換。

      十進制轉(zhuǎn)二進制

      基于 “除二取余” 思路實現(xiàn)

      function toBinary(value) {
          if (isNaN(Number(value))) {
              throw `${value} is not a number` 
          }
          let bits = []
          while (value >= 1) {
              bits.unshift(value % 2)
              value = Math.floor(value / 2)
          }
          return bits.join('')
      }
      

      使用

      toBinary(36) // 100100
      toBinary(12) // 1100
      

      二進制轉(zhuǎn)十進制

      基于 “取冪相加” 思路實現(xiàn)

      function toDecimal(value) {
          let bits = value.toString().split('')
          let res = 0
          while (bits.length) {
              let bit = bits.shift()
              if (bit == 1) {
                  // ** 為冪運算符,如:2**3 為 8
                  res += 2 ** bits.length
              }
          }
          return res
      }
      

      使用

      toDecimal(10011) // 19
      toDecimal(11111) // 33
      

      寫在最后

      本文為大家介紹了進制和位運算的相關知識,旨在溫故知新。我們只需要大概了解就好,因為在開發(fā)中真的用得少,至少我只用過 ~~ 來取整。而類似于~~這種取整操作還是盡量少用為好,對于其他開發(fā)者來說,可能會影響到代碼可讀性。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多