十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決

創(chuàng)新互聯(lián)建站網(wǎng)絡(luò)公司擁有十余年的成都網(wǎng)站開(kāi)發(fā)建設(shè)經(jīng)驗(yàn),超過(guò)千家客戶的共同信賴。提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、網(wǎng)站開(kāi)發(fā)、網(wǎng)站定制、友情鏈接、建網(wǎng)站、網(wǎng)站搭建、成都響應(yīng)式網(wǎng)站建設(shè)公司、網(wǎng)頁(yè)設(shè)計(jì)師打造企業(yè)風(fēng)格,提供周到的售前咨詢和貼心的售后服務(wù)
位運(yùn)算一般用于操作整數(shù),對(duì)整數(shù)進(jìn)行位運(yùn)算才有實(shí)際的意義。整數(shù)在內(nèi)存中是以補(bǔ)碼形式存儲(chǔ)的,正數(shù)的補(bǔ)碼形式和原碼形式相同,而負(fù)數(shù)的補(bǔ)碼形式和它的原碼形式是不一樣的,這一點(diǎn)大家要特別注意;這意味著,對(duì)負(fù)數(shù)進(jìn)行位運(yùn)算時(shí),操作的是它的補(bǔ)碼,而不是它的原碼。
對(duì)整數(shù)存儲(chǔ)不了解的讀者請(qǐng)猛擊《整數(shù)在內(nèi)存中是如何存儲(chǔ)的,為什么它堪稱(chēng)天才般的設(shè)計(jì)》。
mysql 中的整數(shù)字面量(常量整數(shù),也就是直接書(shū)寫(xiě)出來(lái)的整數(shù))默認(rèn)以 8 個(gè)字節(jié)(Byte)來(lái)表示,也就是 64 位(Bit)。例如,5 的二進(jìn)制形式為:
0000 0000 ... 0000 0101
省略號(hào)部分都是 0,101 前面總共有 61 個(gè) 0。
注意:為了方便大家閱讀,本節(jié)在介紹正數(shù)的補(bǔ)碼時(shí),省略了前面的 0。
MySQL 支持 6 種位運(yùn)算符,如下表所示。
| 運(yùn)算符 | 說(shuō)明 | 使用形式 | 舉例 |
|---|---|---|---|
| | | 位或 | a | b | 5 | 8 |
| & | 位與 | a & b | 5 & 8 |
| ^ | 位異或 | a ^ b | 5 ^ 8 |
| ~ | 位取反 | ~a | ~5 |
| << | 位左移 | a << b | 5 << 2,表示整數(shù) 5 按位左移 2 位 |
| >> | 位右移 | a >> b | 5 >> 2,表示整數(shù) 5 按位右移 2 位 |
位運(yùn)算中的
&、
|、
~和邏輯運(yùn)算中的
&&、
||、
!非常相似。
參與
|運(yùn)算的兩個(gè)二進(jìn)制位有一個(gè)為 1 時(shí),結(jié)果就為 1,兩個(gè)都為 0 時(shí)結(jié)果才為 0。例如
1|1結(jié)果為 1,
0|0結(jié)果為0,
1|0結(jié)果為1,這和邏輯運(yùn)算中的
||非常類(lèi)似。
使用位或運(yùn)算符進(jìn)行正數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT 10|15,9|4|2; +-------+-------+ | 10|15 | 9|4|2 | +-------+-------+ | 15 | 15 | +-------+-------+ 1 row in set (0.00 sec)
10 的補(bǔ)碼為 1010,15 的補(bǔ)碼為 1111,按位或運(yùn)算之后,結(jié)果為 1111,即整數(shù) 15;9 的補(bǔ)碼為 1001,4 的補(bǔ)碼為 0100,2 的補(bǔ)碼為 0010,按位或運(yùn)算之后,結(jié)果為 111,即整數(shù) 15。
使用位或運(yùn)算符進(jìn)行負(fù)數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT -7|-1; +----------------------+ | -7|-1 | +----------------------+ | 18446744073709551615 | +----------------------+ 1 row in set (0.00 sec)
-7 的補(bǔ)碼為 60 個(gè)‘1’加 1001,-1 的補(bǔ)碼為 64 個(gè)‘1’,按位或運(yùn)算之后,結(jié)果為 64 個(gè)‘1’,即整數(shù) 18446744073709551615。
可以發(fā)現(xiàn),
任何數(shù)和 -1 進(jìn)行位或運(yùn)算時(shí),最終結(jié)果都是 -1 的十進(jìn)制數(shù)。
參與
&運(yùn)算的兩個(gè)二進(jìn)制位都為 1 時(shí),結(jié)果就為 1,否則為 0。例如
1|1結(jié)果為 1,
0|0結(jié)果為 0,
1|0結(jié)果為 0,這和邏輯運(yùn)算中的
&&非常類(lèi)似。
使用位與運(yùn)算符進(jìn)行正數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT 10 & 15,9 & 4 & 2; +---------+-----------+ | 10 & 15 | 9 & 4 & 2 | +---------+-----------+ | 10 | 0 | +---------+-----------+ 1 row in set (0.00 sec)
10 的補(bǔ)碼為 1010,15 的補(bǔ)碼為 1111,按位與運(yùn)算之后,結(jié)果為 1010,即整數(shù) 10;9 的補(bǔ)碼為 1001,4 的補(bǔ)碼為 0100,2 的補(bǔ)碼為 0010,按位與運(yùn)算之后,結(jié)果為 0000,即整數(shù) 0。
使用位與運(yùn)算符進(jìn)行負(fù)數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT -7&-1; +----------------------+ | -7&-1 | +----------------------+ | 18446744073709551609 | +----------------------+ 1 row in set (0.01 sec)
-7 的補(bǔ)碼為 60 個(gè)‘1’加 1001,-1 的補(bǔ)碼為 64 個(gè)‘1’,按位與運(yùn)算之后,結(jié)果為 60 個(gè)‘1’加 1001,即整數(shù) 18446744073709551609。
可以發(fā)現(xiàn),
任何數(shù)和 -1 進(jìn)行位與運(yùn)算時(shí),最終結(jié)果都為任何數(shù)本身的十進(jìn)制數(shù)。
參與
^運(yùn)算的兩個(gè)二進(jìn)制位不同時(shí),結(jié)果為 1,相同時(shí),結(jié)果為 0。例如
1|1結(jié)果為 0,
0|0結(jié)果為 0,
1|0結(jié)果為1。
使用位異或運(yùn)算符進(jìn)行正數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT 10^15,1^0,1^1; +-------+-----+-----+ | 10^15 | 1^0 | 1^1 | +-------+-----+-----+ | 5 | 1 | 0 | +-------+-----+-----+ 1 row in set (0.00 sec)
10 的補(bǔ)碼為 1010,15 的補(bǔ)碼為 111,按位異或運(yùn)算之后,結(jié)果為 0101,即整數(shù) 5;1 的補(bǔ)碼為 0001,0 的補(bǔ)碼為 0000,按位異或運(yùn)算之后,結(jié)果為 0001;1 和 1 本身二進(jìn)制位完全相同,因此結(jié)果為 0。
使用位異或運(yùn)算符進(jìn)行負(fù)數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT -7^-1; +-------+ | -7^-1 | +-------+ | 6 | +-------+ 1 row in set (0.00 sec)
-7 的補(bǔ)碼為 60 個(gè)‘1’加 1001,-1 的補(bǔ)碼為 64 個(gè)‘1’,按位異或運(yùn)算之后,結(jié)果為 110,即整數(shù) 6。
位左移是按指定值的補(bǔ)碼形式進(jìn)行左移,左移指定位數(shù)之后,左邊高位的數(shù)值被移出并丟棄,右邊低位空出的位置用 0 補(bǔ)齊。
位左移的語(yǔ)法格式為:
expr << n
其中,n 指定值 expr 要移位的位數(shù),n 必須為非負(fù)數(shù)。
使用位左移運(yùn)算符進(jìn)行正數(shù)計(jì)算,SQL 語(yǔ)句如下:
mysql> SELECT 1<<2,4<<2; +------+------+ | 1<<2 | 4<<2 | +------+------+ | 4 | 16 | +------+------+ 1 row in set (0.00 sec)
1 的補(bǔ)碼為 0000 0001,左移兩位之后變成 0000 0100,即整數(shù) 4;4 的補(bǔ)碼為 0000 0100,左移兩位之后變成 0001 0000,即整數(shù) 16。
使用位左移運(yùn)算符進(jìn)行負(fù)數(shù)計(jì)算,SQL 語(yǔ)句如下:
mysql> SELECT -7<<2; +----------------------+ | -7<<2 | +----------------------+ | 18446744073709551588 | +----------------------+ 1 row in set (0.00 sec)
-7 的補(bǔ)碼為 60 個(gè)‘1’加 1001,左移兩位之后變成 56 個(gè)‘1’加 1110 0100,即整數(shù) 18446744073709551588。
位右移是按指定值的補(bǔ)碼形式進(jìn)行右移,右移指定位數(shù)之后,右邊低位的數(shù)值被移出并丟棄,左邊高位空出的位置用 0 補(bǔ)齊。
位右移語(yǔ)法格式為:
expr >> n
其中,n 指定值 expr 要移位的位數(shù),n 必須為非負(fù)數(shù)。
使用位右移運(yùn)算符進(jìn)行正數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT 1>>1,16>>2; +------+-------+ | 1>>1 | 16>>2 | +------+-------+ | 0 | 4 | +------+-------+ 1 row in set (0.00 sec)
1 的補(bǔ)碼為 0000 0001,右移 1 位之后變成 0000 0000,即整數(shù) 0;16 的補(bǔ)碼為 0001 0000,右移兩位之后變成 0000 0100,即整數(shù) 4。
使用位右移運(yùn)算符進(jìn)行負(fù)數(shù)運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT -7>>2; +---------------------+ | -7>>2 | +---------------------+ | 4611686018427387902 | +---------------------+ 1 row in set (0.00 sec)
-7 的補(bǔ)碼為 60 個(gè)‘1’加 1001,右移兩位之后變成 0011 加 56 個(gè)‘1’加 1110,即整數(shù) 4611686018427387902。
位取反是將參與運(yùn)算的數(shù)據(jù)按對(duì)應(yīng)的補(bǔ)碼進(jìn)行反轉(zhuǎn),也就是做 NOT 操作,即 1 取反后變 0,0 取反后變?yōu)?1。
下面看一個(gè)經(jīng)典的取反例子,對(duì) 1 進(jìn)行位取反運(yùn)算,具體如下所示:
mysql> SELECT ~1,~18446744073709551614; +----------------------+-----------------------+ | ~1 | ~18446744073709551614 | +----------------------+-----------------------+ | 18446744073709551614 | 1 | +----------------------+-----------------------+ 1 row in set (0.00 sec)
常量 1 的補(bǔ)碼為 63 個(gè)‘0‘加 1 個(gè)’1‘,位取反后就是 63 個(gè)’1‘加一個(gè)’0‘,轉(zhuǎn)換為二進(jìn)制后就是 18446744073709551614。
可以使用 BIN() 函數(shù)查看 1 取反之后的結(jié)果,BIN() 函數(shù)的作用是將一個(gè)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù),SQL 語(yǔ)句如下:
mysql> SELECT BIN(~1); +------------------------------------------------------------------+ | BIN(~1) | +------------------------------------------------------------------+ | 1111111111111111111111111111111111111111111111111111111111111110 | +------------------------------------------------------------------+ 1 row in set (0.01 sec)
1 的補(bǔ)碼表示為最右邊位為 1,其他位均為 0,取反操作之后,除了最低位,其他位均變?yōu)?1。
使用位取反運(yùn)算符進(jìn)行運(yùn)算,SQL 語(yǔ)句如下:
mysql> SELECT 5 & ~1; +--------+ | 5 & ~1 | +--------+ | 4 | +--------+ 1 row in set (0.00 sec)
邏輯運(yùn)算
5&~1 中,由于位取反運(yùn)算符‘~’的級(jí)別高于位與運(yùn)算符‘&’,因此先對(duì) 1 進(jìn)行取反操作,結(jié)果為 63 個(gè)‘1’加一個(gè)‘0’,然后再與整數(shù) 5 進(jìn)行與運(yùn)算,結(jié)果為 0100,即整數(shù) 4。