上一章咱們學習了按位操做符 帶你認識按位操做符html
這一章咱們整理一下按位運算的經典案例markdown
使用按位操做符的數,會先轉成 32 位比特序列,也就是32 位的有符號的整數app
若是這個數是正數,若是大於 ,只會保留低 32 位, 高於 32 位的數不存儲;函數
若是這個數是負數,若是小於 ,只會保留低 32 位, 高於 32 位的數不存儲;oop
按位與(&)
兩個二進制數, 它們對應位的數都是 1 時, 結果爲 1, 不然, 結果爲 0。post
12.12 & 12.12 //12
Math.PI & Math.PI //3
複製代碼
JavaScript 默認將數字存儲爲 64 位浮點數,但按位運算都是以 32位的二進制整數執行。學習
兩個相同的數按位運算後, 結果只會保留整數部分,小數部分在轉行階段不存儲。spa
Infinity & Infinity //0
Number.MAX_VALUE & Number.MAX_VALUE //0
複製代碼
若是一個數大於 因爲按位運算時只會保留低 32 位運算, 高於 32位的數丟棄, 結果就不許確了。code
function assert(x) {
return x & 1;
}
assert(3) //1 若是返回1是奇數,不然是偶數。
複製代碼
x 是任意正整數,這裏咱們用 x = 3舉例子,那麼, 3 & 1
轉成32 位比特序列就是:orm
3 (base 10) = 00000000000000000000000000000011 (base 2)
1 (base 10) = 00000000000000000000000000000001 (base 2)
--------------------------------
3 & 1 (base 10) = 00000000000000000000000000000001 (base 2) = 1 (base 10)
複製代碼
3 & 1
的結果是 1,是奇數。咱們再來一個例子:
4 (base 10) = 00000000000000000000000000000100 (base 2)
1 (base 10) = 00000000000000000000000000000001 (base 2)
--------------------------------
4 & 1 (base 10) = 00000000000000000000000000000000 (base 2) = 0 (base 10)
複製代碼
4 & 1
的結果是 0,是偶數。
編寫一個函數,輸入是一個無符號整數(以二進制串的形式),返回其二進制表達式中數字位數爲 '1' 的個數(也被稱爲 漢明重量).)。
function hammingWeight(x) {
count = 0
while(x){
x = x & (x - 1);
count++;
}
return count;
}
hammingWeight(6) //2
複製代碼
這裏咱們用x = 6帶入, 那麼 x - 1 = 5, 5 & 6
的結果是多少, 咱們畫圖理解。
6 (base 10) = 00000000000000000000000000000110 (base 2)
5 (base 10) = 00000000000000000000000000000101 (base 2)
--------------------------------
6 & 5 (base 10) = 00000000000000000000000000000100 (base 2) = 4 (base 10) count++;
3(base 10) = 00000000000000000000000000000011 (base 2)
--------------------------------
4 & 3(base 10) = 00000000000000000000000000000000 (base 2) = 0 (base 10) count++;
複製代碼
咱們一共執行了兩次x = x & (x - 1)
, 因此也會執行兩次count++
, 第三次開始執行 while 時, x = 0
, 跳出循環,返回結果 2
;
經過畫圖理解, 由於二進制是滿 2 進 1,因此 x & (x - 1)
剛好能夠把x 的二進制位中的最低位的 1 變成 0。 每次都會把二進制 x 中的一個 1 變成 0 , 統計執行x & (x - 1)
異或的次數, 就是 「1」 的個數。
x & n - 1
, 總能把x最低位的 1變爲 0, 其餘位保持不變。