~按位取反運算符
正常一個數(shù)字,例如1
和2
纲爸,或者-1
和-2
阁危。
如果我們對它們進行按位取反的話,結果會是這樣:
~1 = -2
~2 = -3
~-1 = 0
~-2 = 1
看不懂沒關系亮瓷,讓我們來一步步看看實現(xiàn)的過程哈。
在這里其實是分了正數(shù)和負數(shù)的降瞳,因為符號不同取反的過程也會不同。
1.1 正數(shù)按位取反
先讓我們來看看正數(shù)的按位取反蚓胸。
比如先看看~1 = -2
挣饥,過程如下:
1. 十進制轉為二進制原碼
首先將十進制的1
轉化為二進制原碼為:0000 0001
2. 二進制原碼按位取反
之后將原碼按位取反:
也就是將0000 0001
=> 1111 1110
(取反應該知道啥意思吧?就是0
換成1
沛膳,1
換成0
)
3. 取反后的二進制轉為原碼
再將取反后的二進制碼轉為原碼二進制:
也就是將1111 1110
=> 1000 0010
這里你估計看著都點懵了扔枫,當我們將取反后的二進制轉為原碼二進制的時候,其實是有以下兩步的:
- 需要判斷取反后的二進制的第一個位是不是
1
锹安,這個第一位我們稱之為符號位短荐,如果是1
的話就表示即將要轉成的數(shù)是一個負數(shù),如果是0
的話表示即將要轉的數(shù)是一個正數(shù)叹哭,這個符號位是不能動的忍宋;在這里我們可以看到1111 1110
的第一位是1
,所以表示即將要轉的數(shù)是一個負數(shù)风罩,同時我們不動它糠排。 - 然后將除了第一位以外其它位數(shù)取反并
+1
。所以會有這么兩個過程:-
1111 1110
=>1000 0001
-
1000 0001
=>1000 0010
(這步是對上一步的結果+1
超升,因為上一步的最后一個數(shù)是1
入宦,所以它再加上1
就需要向前進一位了哺徊,因此變成了1000 0010
)
-
4. 將原碼二進制轉為十進制
最后一步就是將我們前面得到的1000 0010
這個二進制轉化為十進制了。
第一位符號位乾闰,是1
落追,則表示是個負數(shù),所以結果為-2
涯肩。
OK??轿钠,搞懂了這個步驟之后再讓我們自己來轉換一下~2 = -3
吧:
1. 0000 0010
2. 1111 1101
3. 1000 0011
4. -3
正數(shù)按位取反總結
- 十進制轉為二進制原碼
- 二進制原碼按位取反
- 符號位保留,其余位取反+1
- 二進制原碼轉為十進制
1.2 負數(shù)按位取反
負數(shù)的按位取反和上面就有些不一樣了宽菜,主要是第二步和第三步調換一下順序:
- 十進制轉為二進制原碼
- 符號位保留谣膳,其余位取反+1
- 二進制原碼按位取反
- 二進制原碼轉為十進制
例如:~-1 =0
的轉換過程:
1. 十進制轉為二進制原碼
這步和正數(shù)按位取反是一樣的:
-1
=> 1000 0001
2. 符號位保留,其余位取反+1
轉換過程:
-
1000 0001
=>1111 1110
(取反) -
1111 1110
=>1111 1111
(取反后 + 1)
3. 二進制原碼按位取反
將剛剛得到的再進行按位取反:
1111 1111
=> 0000 0000
4. 二進制原碼轉為十進制
0000 0000
=> 0
OK??铅乡,現(xiàn)在自己來轉換一下~-2 = 1
吧:
1. 1000 0010
2. 1111 1110
3. 0000 0001
4. 1
這里沒啥訣竅继谚,關鍵就是要記住轉換的過程然后不斷的練習吧 ??。
~~雙非按位取反運算符
~~它代表雙非按位取反運算符阵幸,如果你想使用比Math.floor()
更快的方法花履,那就是它了。它有這么兩個特點:
- 非數(shù)字取值為
0
挚赊,它具體的表現(xiàn)形式為:
~~null; // => 0
~~undefined; // => 0
~~Infinity; // => 0
--NaN; // => 0
~~0; // => 0
~~{}; // => 0
~~[]; // => 0
~~(1/0); // => 0
~~false; // => 0
~~true; // => 1
對比與Number()
的好處就是Number(undefined)
會轉換為NaN
诡壁;但是使用~~
能保證一直是數(shù)字。
- 對于正數(shù)荠割,它向下取整妹卿;對于負數(shù),向上取整:
console.log(~~1.3) // 1
console.log(~~-1.3) // -1
與Math.floor()
的不同蔑鹦,Math.floor()
都是向下取整:
console.log(Math.floor(1.3)) // 1
console.log(Math.floor(-1.3)) // -2
console.log(~~1.3) // 1
console.log(~~-1.3) // -1
|運算符
通常用來取整夺克,如:
1.2|0 // 1
1.8|0 // 1
-1.2|0 // -1
其它運算符
類似的還有:
<<左移,<<a 將a第一位丟棄嚎朽,后七位尾部加0
>>右移铺纽,>>a 將a末位丟棄,前七位開頭加0
& 或哟忍,a & b 將a和b中所有為1的位組成新值
^ 異狡门,a ^ b 將a和b中ab不同的位組(即其中一個為0且另一個為1,則為1锅很,兩個都為0或都為1其馏,則為0)成新值