十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
|= 是JavaScript中按位“或”賦值運算符
成都創(chuàng)新互聯(lián)公司自2013年起,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務公司,擁有項目成都做網(wǎng)站、成都網(wǎng)站制作網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元阿克陶做網(wǎng)站,已為上家服務,為阿克陶各地企業(yè)和個人服務,聯(lián)系電話:028-86922220
JavaScript中按位“或”賦值運算符是對變量值與表達式值執(zhí)行按位“或”,并將結(jié)果賦給該變量。使用方法:
result |= expression
其中result是任何變量。
expression是任何表達式。
JavaScript中按位“或”賦值運算符,使用該運算符和使用下面的語句是等效的:
result = result | expression
|= 運算符查看 result 和 expression 的二進制表示法的值,并執(zhí)行按位“或”操作。該操作的結(jié)果如下所示:
0101 (result)
1100 (expression)
----
1101 (輸出)
任何時候,只要兩個表達式中的其中一個的某位是 1,則結(jié)果的該位是 1。否則,結(jié)果的該位是 0。
在了解位運算之前, 必須先了解一下什么是原碼, 反碼和補碼, 以及二進制與十進制的轉(zhuǎn)換.
原碼
一個數(shù)在計算機中是以二進制的形式存在的, 其中第一位存放符號, 正數(shù)為0, 負數(shù)為1. 原碼就是用第一位存放符號的二進制數(shù)值. 例如2的原碼為00000010, -2的原碼為10000010
反碼
正數(shù)的反碼是它本身, 負數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號位不變, 其余各位取反.
可見如果一個反碼表示的是負數(shù), 并不能直觀的看出它的數(shù)值, 通常要將其轉(zhuǎn)換成原碼再計算
補碼
正數(shù)的補碼是它本身, 負數(shù)的補碼是在其原碼基礎(chǔ)上, 符號位不變, 其余各位取反, 最后+1. (即負數(shù)的補碼為在其反碼的基礎(chǔ)上+1)
可見對于負數(shù), 補碼的表示方式也是讓人無法直觀的看出其數(shù)值的, 通常也需要轉(zhuǎn)換成原碼再計算.
正整數(shù)十進制轉(zhuǎn)二進制
正整數(shù)的十進制轉(zhuǎn)二進制的方法為將一個十進制數(shù)除以2, 得到的商再除以2, 以此類推知道商為1或0時為止, 倒序取得除得的余數(shù), 即為轉(zhuǎn)換所得的二進制數(shù).
負整數(shù)十進制轉(zhuǎn)二進制
負整數(shù)的十進制轉(zhuǎn)二進制, 先將該負整數(shù)對應的正整數(shù)轉(zhuǎn)為二進制, 然后對其取反再+1. 即補碼的形式
十進制小數(shù)轉(zhuǎn)二進制
十進制小數(shù)轉(zhuǎn)二進制的方法為"乘2取整", 對十進制的小數(shù)部分乘2, 得到的整數(shù)部分即是相應的二進制碼數(shù), 然后繼續(xù)對得到的小數(shù)部分乘2, 如此不斷重復, 直到小數(shù)部分為0或達到精度要求為止. 順序取得每次的整數(shù)部分, 即是該十進制小數(shù)的二進制表示.
按位運算符有6個
: 按位與
|: 按位或
^: 按位異或
~: 按位取反
: 右移
: 左移
將運算數(shù)以二進制表示, 對應位都為1, 則結(jié)果為1, 否則為0.
使用場景示例:
判斷一個數(shù)是奇數(shù)還是偶數(shù)
奇數(shù)的二進制碼的最后一位數(shù)肯定是1, 而1只有最后一位為1, 按位與運算后, 結(jié)果肯定只有最后一位數(shù)是1. 而偶數(shù)的二進制表示的最后一位數(shù)是0, 和1進行按位與運算, 結(jié)果的所有位都是0.
將運算數(shù)以二進制表示, 對應位有一個為1, 則結(jié)果為1, 否則為0.
使用場景示例:
對浮點數(shù)向下求整
其實浮點數(shù)是不支持位運算的, 所以會先把小數(shù)位丟棄, 然后以整數(shù)進行位運算, 而任何數(shù)與0進行按位或操作, 結(jié)果都是它本身, 就好像是對浮點數(shù)向下求整.
將運算數(shù)以二進制表示, 對應位相同為0, 相異為1.
異或滿足交換律和結(jié)合律, 數(shù)字與它本身進行異或操作, 得到0; 數(shù)字與0進行異或操作, 得到它本身.
使用場景示例:
交換兩個變量數(shù)字的值
將操作數(shù)轉(zhuǎn)換為二進制數(shù), 然后按位求反.
浮點數(shù)是不支持位運算的,所以會先直接去除小數(shù)部分,轉(zhuǎn)成整數(shù)再進行位運算,就好像是對浮點數(shù)向下求整.
~~可以進行類型轉(zhuǎn)換,位運算會默認將非數(shù)字類型轉(zhuǎn)換成數(shù)字類型再進行運算 (轉(zhuǎn)換結(jié)果為整數(shù) 直接去除小數(shù)部分)
使用場景示例:
類型轉(zhuǎn)換
移位運算符將操作數(shù)轉(zhuǎn)換成二進制, 然后向左或向右移動, 超過的位丟棄, 空出的位補0.
使用場景示例:
類型轉(zhuǎn)換
任何小數(shù) 把它 0可以取整
如3.14159 0 = 3;
其默認將非數(shù)字類型的轉(zhuǎn)換為數(shù)字類型再做運算的性質(zhì)與 ~~ , | 0 一樣
| 是或運算符
或運算的基本原理是:兩個數(shù)相對應的位都為1或其中一個為1則結(jié)果為1,如果都是0則結(jié)果為0。
比如:
4 的各位為 0100
8 的各位為 1000
那么 4|8 就是 1100
轉(zhuǎn)換為10進制就是12
通俗點來理解,或運算可以使兩種狀態(tài)進行疊加,比如
0100 代表勇敢
1000 代表機智
那么經(jīng)過或運算的結(jié)果1100就代表既勇敢又機智
如果1100再和0100進行或運算,結(jié)果仍然是1100,因為1100已經(jīng)包含0100這個狀態(tài)了
不知你聽明白了沒有?
按位操作符(Bitwise operators)會使用內(nèi)置函數(shù), 7.1.5 ToInt32 ( argument ) ,
先將其操作數(shù)轉(zhuǎn)換成32位有符號整數(shù) ,再進行位操作,最后返回一個32位有符號整數(shù)。
包括,
12.5.8 Bitwise NOT Operator ( ~ ) ,
12.9.3 The Left Shift Operator ( ) ,
12.9.4 The Signed Right Shift Operator ( ) ,
12.12 Binary Bitwise Operators
因此, a | 0 , 0 | a ,都可以將變量 a 中數(shù)值轉(zhuǎn)換為32位有符號整數(shù)。
某些特殊的值,并不是32位有符號整數(shù)的安全范圍,它們會被轉(zhuǎn)換為 0 。
在計算機中表示有符號整數(shù),通常使用 補碼 (two's-complement)進行編碼。
它將字的最高有效位解釋為符號位,符號位被置為 1 時,表示值為負,
符號位被置為 0 時,表示值為非負。
因此,字長為4的二進制數(shù) 0001 表示整數(shù) 1 ,其中 0*2^3+0*2^2+0*2^1+1*2^0=1 ,
而 1111 就表示整數(shù) -1 ,其中 -1*2^3+1*2^2+1*2^1+1*2^0=-1 。
負數(shù)的補碼,還可以按照“ 逐位取反后,加一 ”的方式來獲取相應的整數(shù)值。
例如, 1111 逐位取反 0000 ,然后再加一 0001 ,它是 1 的二進制表示,
因此 1111 就是表示 -1 了。
~ 操作符,它首先將操作數(shù)轉(zhuǎn)換成32位有符號整數(shù),然后再按位取反。
例如, 1 的32位補碼編碼為,
按位取反,
它表示什么呢?
先看最高為的符號位,是 1 ,它表示一個負數(shù),
然后“逐位取反后,加一”, 00000000 00000000 00000000 00000002 值為 2 ,
因此, 11111111 11111111 11111111 11111110 表示 -2 。
一般的, 可以證明 ,
對于任意的32位有符號整數(shù) x 來說, ~x === -(x+1) 。
詳細證明見文后的附錄。
ECMAScript中,數(shù)組元素的索引范圍是, 0 到 Math.pow(2,32)-2 。
規(guī)范 9.4.2 Array Exotic Objects 中指出,
超過數(shù)組 length 的索引,會被看做數(shù)組的屬性值,
因此, indexOf 返回的最大值為 Math.pow(2,32)-2 。
Array.prototype.indexOf ,
會返回給定數(shù)組元素在數(shù)組中的索引,如果找不到給定元素,就返回 -1 。
因為只有 ~-1 等于 0 ,其他索引值取反都非 0 ,
所以,人們經(jīng)常使用 !~a.indexOf(element) 來判斷元素是否在數(shù)組中。
這里有一個值得注意的事情,由于 ~ 會首先將操作數(shù)轉(zhuǎn)換成32位有符號整數(shù),
所以, -1 和 Math.pow(2,32)-1 具有相同的編碼,
但是,數(shù)組的最大索引為 Math.pow(2,32)-2 ,小于上面這個值,
因此,對 indexOf 返回的值進行取反,除了 -1 之外,總是非 0 值,是安全的做法。
下面給出 ~x === -(x+1) 的證明。
(1)先看正整數(shù)
對于32位正整數(shù)來說,它的二進制編碼為,
其中 n 表示 0 或者 1 ,
則, ~x 為,
其中 u 為 n 的取反結(jié)果。
以上二進制表示,如果看成32位有符號整數(shù),則由于符號位 1 ,它是一個負數(shù),
其絕對值為,“逐位取反后,加一”,即為, (0nnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn)+1 === x+1 ,
即, -(x+1) 。
因此,對于正數(shù), ~x === -(x+1) 。
(2)再看負整數(shù)
對于32位負整數(shù)來說,它的二進制編碼為,
其中 n 表示 0 或者 1 ,
則, ~x 為,
其中 u 為 n 的取反結(jié)果。
設(shè) 0uuuuuuu uuuuuuuu uuuuuuuu uuuuuuuu 的值為 t ,
則 1nnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn 的值為, -(t+1) ,(逐位取反后,加一)。
因此, x === -(t+1) , ~x === t ,
即, ~x === t === -(-(t+1) + 1) === -(x+1) 。
證畢。
你不知道的JavaScript(中卷)
ECMAScript Language Specification
深入理解計算機系統(tǒng)