> Javascript 按位取反運算符 (~) ,對一個表達式執(zhí)行位非(求非)運算。如 ~1 = -2 ; ~2 = -3 ; ~99 = -100
`result = ~ 【數(shù)字】`
所有一元運算符(如 ~ 運算符)都按照下面的規(guī)則來計算表達式的值:
代碼如下:
```js
1、 如果應(yīng)用于未定義的表達式或 null 表達式,則會引發(fā)一個運行時錯誤。
2、 將對象轉(zhuǎn)換為字符串。
3、 如果可能,將字符串轉(zhuǎn)換為數(shù)字。 否則,將引發(fā)運行時錯誤。
4、 布爾值被視為數(shù)字(如果為 false,則為 0;如果為 true,則為 1)。
```
運算符將應(yīng)用于結(jié)果數(shù)字。
`~` 運算符查看表達式的二進制表示形式的值,并執(zhí)行位非運算。
表達式中的任何一位為 1,則結(jié)果中的該位變?yōu)?0。 表達式中的任何一位為 0,則結(jié)果中的該位變?yōu)?1。
下面的示例闡釋了位非 (~) 運算符的用法,其中包含二進制表示十進制負數(shù)的,如果不熟悉這個請先看懂*《十進制負數(shù)轉(zhuǎn)換為二進制、八進制、十六進制》*。
```javascript
代碼如下:
var temp = ~5;
/*
5 二進制 101,補滿 32位
00000000000000000000000000000101
按位取反
11111111111111111111111111111010
由于32位開頭第一個是1,所以這是一個負數(shù),將二進制轉(zhuǎn)換成負數(shù),需要先反碼
00000000000000000000000000000101
之后,再+1
00000000000000000000000000000110
轉(zhuǎn)換成十進制為6,加上符號變成負數(shù) -6
*/
alert(temp);
// 彈出【-6】
```
## 十進制負數(shù)轉(zhuǎn)換為二進制、八進制、十六進制
程序猿們或許對二進制都不陌生,二進制是計算技術(shù)中廣泛采用的一種數(shù)制。二進制數(shù)據(jù)是用0和1兩個數(shù)碼來表示的數(shù)。但是很多人都會將二進制轉(zhuǎn)換成整數(shù),但是如何用二進制表示負數(shù)呢?有的人會說,在二進制前面加個負數(shù)符合。而計算機只能認識0 和 1,又怎么去加個額外的負數(shù)符號呢?于是我們就需要用0和1來表示負數(shù)。如果想要弄懂這個,我們需要先了解什么是二進制原碼。
### 原碼是什么
原碼(true form)是一種計算機中對數(shù)字的二進制定點表示方法。原碼表示法在數(shù)值前面增加了一位符號位(即最高位為符號位):正數(shù)該位為0,負數(shù)該位為1(0有兩種表示:+0和-0),其余位表示數(shù)值的大小。
簡單直觀;例如,我們用8位二進制表示一個數(shù),+11的原碼為`00001011`,-11的原碼就是10001011
原碼不能直接參加運算,可能會出錯。例如數(shù)學上,`1+(-1)=0`,而在二進制中`00000001 + 10000001 = 10000010`,換算成十進制為-2。顯然出錯了。

### 二進制原碼、補碼和反碼
十進制如何轉(zhuǎn)換成二進制
我們?nèi)绾伟咽M制的-3,轉(zhuǎn)換成二進制表示呢?首先我們將 -3 的絕對值 +3 轉(zhuǎn)換成二進制,假設(shè)是為int類型(32位)的,那么二進制表示為:
`0000 0000 0000 0000 0000 0000 0000 0011`
#### 負數(shù)轉(zhuǎn)換成二進制分為3步:
**1、** 首先將負數(shù)轉(zhuǎn)換為對應(yīng)的原碼
-3 的原碼為(也就是+3轉(zhuǎn)換成二進制后的字符串):
`0000 0000 0000 0000 0000 0000 0000 0011`
**2、** 再將原碼的每一位做取反操作得到反碼。
取反操作:0變?yōu)? 、 1變?yōu)?;取反后的結(jié)果即為:
`1111 1111 1111 1111 1111 1111 1111 1100`
**3、** 將反碼+1得到補碼
`1111 1111 1111 1111 1111 1111 1111 1101`
現(xiàn)在用Windows自帶的計算器來驗證一下,Win+R 輸入calc,將計算器改為程序員,選擇雙字(4字節(jié),32位)

打開Windows自帶的計算器科學計算功能
**在計算器中選擇十進制,之后輸入 -3** :

再點擊二進制轉(zhuǎn)換,將十進制下的-3轉(zhuǎn)換成二進制:

### 二進制轉(zhuǎn)十進制負數(shù)問題
正常情況下,轉(zhuǎn)換二進制到十進制都是沒有任何問題的。而在類似 Javascript / PHP 等整數(shù)類型中,一般 int /integer 都有位數(shù)限制,一般都是32位長度。也就預示著,這些語言中,整數(shù)是有最大值的,而32位最大整數(shù)極限為:2147483647,也就是二進制:
`01111111111111111111111111111111`
那么就很容易理解,32位二進制,第一位數(shù)為0的時候,就表示這個是一個正數(shù),而如果是1,那么就表示這個是負數(shù)。
32位二進制 `11111111111111111111111111111001` 十進制值是什么?
`11111111111111111111111111111001`
如上,二進制長度為32位,也就是這個整數(shù)是一個負數(shù),先取反,得到反碼:
`00000000000000000000000000000110`
反碼+1,得到:
`00000000000000000000000000000111`
轉(zhuǎn)換成十進制:7
由于是負數(shù),所以加個負號,轉(zhuǎn)換成 -7
**趣味:32位二進制 1111111111111111111111111111001 十進制值是什么?**
這個是個比較有趣的,千萬不要誤導為上面這是一個負數(shù),其實這個是個整數(shù),因為這里只有31位,需要在前面加0,補足32位,變成:
`01111111111111111111111111111001`
### 十進制負數(shù)轉(zhuǎn)八進制、十六進制
負數(shù)轉(zhuǎn)換成八進制、十六進制,只需在補碼(二進制)的基礎(chǔ)上,3位合成一位計算,或者4位合成一位計算
-3的轉(zhuǎn)換成二進制為:
`1111 1111 1111 1111 1111 1111 1111 1101`
八進制則將-3的二進制從右至左每3位為一個單元,不夠三位用0補 即:
`011 111 111 111 111 111 111 111 111 111 101`
計算每一個單元,結(jié)果為:`37777777775`
十六進制則將-3的二進制從右至左每4位合并為一個單元,即:
`1111 1111 1111 1111 1111 1111 1111 1101`
計算后為: `FFFFFFFD`

- 步入JavaScript的世界
- 二進制運算
- JavaScript 的版本是怎么回事?
- JavaScript和DOM的產(chǎn)生與發(fā)展
- DOM事件處理
- js的并行加載與順序執(zhí)行
- 正則表達式
- 當遇上this時
- Javascript中apply、call、bind
- JavaScript的編譯過程與運行機制
- 執(zhí)行上下文(Execution Context)
- javascript 作用域
- 分組中的函數(shù)表達式
- JS之constructor屬性
- Javascript 按位取反運算符 (~)
- EvenLoop 事件循環(huán)
- 異步編程
- JavaScript的九個思維導圖
- JavaScript奇淫技巧
- JavaScript:shim和polyfill
- ===值得關(guān)注的庫===
- ==文章==
- JavaScript框架
- Angular 1.x
- 啟動引導過程
- $scope作用域
- $q與promise
- ngRoute 和 ui-router
- 雙向數(shù)據(jù)綁定
- 規(guī)范和性能優(yōu)化
- 自定義指令
- Angular 事件
- lodash
- Test
