JS位運算和遍歷

JS位運算符

整數

  • 有符號整數:容許使用正數和負數,第32位做爲符號位,前31位纔是存儲位
  • 無符號整數:只容許用正數

圖片

  • 若是用n表明位
  • 位數 = 2^n-1
  • 因爲位數(一、二、四、八、16...)中只有第一位| 1 |是奇數,因此能夠根據第一位| 1 |的數值判斷一個數值是奇數仍是偶數
  • num % 2運算本質就是取的| 1 |的值,若是是1就是奇數,是0就是偶數

補碼和反碼

  • 肯定該數字的非負版本的二級製表示const getBinary = num => num.toString(2)
  • 求得二進制反碼,反碼就是把原來的二進制1,0互換。即要把 0 替換爲 1,把 1 替換爲 0
  • 在二進制反碼上加1

位運算NOT~

~的處理過程函數

  • 把運算數轉換成32位數字
  • 把二進制數轉換成它的二進制反碼
  • 把二進制數轉換成浮點數

實質上是對數字求負,而後減1-num - 1code

位運算AND & 和 OR | 和 XOR ^

  • &每一個數字中的數位對齊,位對位進行與運算
  • |每一個數字中的數位對齊,位對位進行或運算
  • ^每一個數字中的數位對齊,位對位進行異或運算
  • JS中的二進制有32位,因此要進行32次運算

有符號移動<<< 、>>>和無符號移動 <<、>>

  • 有符號移動在移動的時候不會移動符號位,即不會移動第32位,而無符號移動會移動符號位
  • 左移<<相等於乘於2,而右移>>至關於除於2

遍歷二進制位結構

因爲二進制的結構是| 16 | 8 | 4 | 2 | 1 |這種結構,位數是從右邊開始的,咱們遍歷要從右邊開始blog

function eachBit(num, callback) {
  while (num) {
    num >>= 1
  }
}
  • 這裏使用了右移的方式遍歷,當num爲0的時候就中止遍歷如10 = (0,1,0,1,0),最靠近左邊的1在第四位2^4-1 = 8| 8 |,因此遍歷了4次
  • 咱們要把遍歷的次數當前的位數以及被右移出去的值(0或1)傳遞給callback
function eachBit(num, callback) {
  let i = 0
  let bitNum = 0
  while (num) {
    // 奇偶位或第一位的值,也即即將被右移出去的值
    const value = num % 2
    
    // 位數 = 2^i
    bitNum = Math.pow(2, i)
    
    callback && callback(value, i, bitNum)
    
    // 右移1位
    num >>= 1
    i++
  }
}

使用遍歷體實現字符串repeat函數

function repeat(str, n) {
  let res = ''
  eachBit(n, v => {
    if (v === 1) {
      res += str
    }
    if (n > 1) {
      str += str
    }
  })
  return res
}
  • 實現思路:因爲字符串要重複的內容是同樣的,爲了減小遍歷次數,採用了eachBit,好比n = 10那麼二進制'1010'只需遍歷四次
  • 注意上面的1對應的數字,第四位1對應| 8 |,第二位1對應| 2 |
  • str += str就是一直迭代,重複次數是2^n(n是遍歷的次數)
  • v === 1的時候也即| 2 |,這時候是str + str2個重複的str| 8 |是8個重複的str
  • 也即str的重複次數是對應| 2 || 8 |的,恰好重複10次
  • n > 1是n等於1,沒有必要再執行迭代了,只會遍歷一次,且v必等於1,後面沒有必要執行了
相關文章
相關標籤/搜索