MySQL涉及二進(jìn)制的運(yùn)算符:位運(yùn)算符

https://www.tiyee.net/post/178.html

獲得MySQL中不同位的數(shù)量
SELECT BIT_COUNT( CONV( '001011', 2, 10 ) ^ CONV( '001111', 2, 10 ) )
SELECT BIT_COUNT( CONV( '001011', 2, 10 ) ^ CONV( '001111', 2, 10 ) )

https://blog.csdn.net/hhj13978064496/article/details/90379886

SELECT data_code,data_value,bin(data_value) as 二進(jìn)制 FROM tb_ceshi_data where data_value & 8

截止目前我們已經(jīng)學(xué)習(xí)了MySQL的三種運(yùn)算符:算術(shù)運(yùn)算符、比較運(yùn)算符、邏輯運(yùn)算符。三者有一個(gè)共同點(diǎn)都是針對(duì)字符型、表達(dá)式和十進(jìn)制的數(shù)字。

那有沒有一種專門為二進(jìn)制數(shù)字提供的運(yùn)算符呢?這就是本問題的主題:位運(yùn)算符。

先看看位運(yùn)算符的定義:

位運(yùn)算符用來對(duì)二進(jìn)制字節(jié)中的位進(jìn)行位移或者測(cè)試處理,MySQL中提供的位運(yùn)算符有按位或(|)、按位與(&)、按位異或(^)、按位左移(<<)、按位右移(>>)、按位取反(~)等運(yùn)算符。

接下來就通過案例的方式來逐一解開這六類位運(yùn)算符的什么面紗。

【1】按位或:|

select 3|8,4|7|10;

如何從十進(jìn)制的角度看待位運(yùn)算的結(jié)果是無法解釋的。所以我們先要把參與操作的數(shù)字轉(zhuǎn)化為二進(jìn)制形式。如下:

【結(jié)論】

3|8就是兩個(gè)二進(jìn)制數(shù)0011與1000進(jìn)行按位或的計(jì)算,對(duì)應(yīng)的二進(jìn)制位有一個(gè)或兩個(gè)為1,運(yùn)算結(jié)果為1,否則為0。所以,3|8的結(jié)果是1011,轉(zhuǎn)化為十進(jìn)制就是11。同理4|7得到0111,再與1010進(jìn)行按位或得到1111,即為十進(jìn)制數(shù)字15。

【2】按位與:&

select 3&8,4&7&10;

規(guī)則:進(jìn)行按位與的計(jì)算,對(duì)應(yīng)的二進(jìn)制位有兩個(gè)為1,運(yùn)算結(jié)果為1,否則為0。

所以我們可以自己得出結(jié)果:3&8 = 0,4&7&10 = 0。

【3】按位異或:^

select 38,47^10;

規(guī)則:進(jìn)行按位異或的計(jì)算,對(duì)應(yīng)的二進(jìn)制位不相同時(shí),運(yùn)算結(jié)果為1,否則為0。

所以我們可以自己得出結(jié)果:3^8 = 11,4710 = 9。

【4】按位左移:<<

select 8<<2,10<<3;

規(guī)則:進(jìn)行按位左移的功能是讓指定二進(jìn)制的所有位都左移指定的位數(shù)。并且在左移指定位數(shù)后,左邊高位的數(shù)值被移出丟棄,右邊地位空出的位置則用0補(bǔ)齊。

8<<2就是二進(jìn)制數(shù)1000向左移動(dòng)2位得到100000,即為十進(jìn)制數(shù)32;10<<3就是二進(jìn)制數(shù)1010向左移動(dòng)3位得到1010000,即為十進(jìn)制數(shù)80。

【5】按位右移:>>

select 8>>2,10>>3;

規(guī)則:進(jìn)行按位右移與按位左移邏輯一致,只是移動(dòng)的方向變成了右邊,即丟地右邊的位數(shù)。

8>>2變成了10,即為十進(jìn)制數(shù)2;10>>3變成了1,即為十進(jìn)制數(shù)1。

【6】按位取反:~

select 8,3&8;

規(guī)則:按位取反是針對(duì)一個(gè)十進(jìn)制數(shù)對(duì)應(yīng)的二進(jìn)制位上的數(shù)字都進(jìn)行取反操作,即0變成1,1變成0,之后再轉(zhuǎn)化為十進(jìn)制得到結(jié)果。

8得到的是:18446744073709551607;3&8則是18446744073709551607轉(zhuǎn)化為二進(jìn)制后與0011進(jìn)行按位與計(jì)算,結(jié)果為3??偨Y(jié)

位運(yùn)算符是針對(duì)二進(jìn)制字節(jié)的操作;位運(yùn)算符有六種類型;學(xué)習(xí)位運(yùn)算符之前,必須要掌握十進(jìn)制與二進(jìn)制之間的互相轉(zhuǎn)換;針對(duì)兩個(gè)操作數(shù)的有:按位或、按位與、按位異或;針對(duì)一個(gè)操作數(shù)的有:按位左移、按位右移、按位取反。

& : 按位與,二進(jìn)制位同時(shí)都為1的位設(shè)為1。
| : 按位或,二進(jìn)制位有一個(gè)位為1就為1.
^ : 按位異或,對(duì)應(yīng)位的二進(jìn)制數(shù)不同時(shí),對(duì)應(yīng)位的結(jié)果才為1;如果兩個(gè)對(duì)應(yīng)位數(shù)都為0或者都為1,則對(duì)應(yīng)位的結(jié)果為0。

原理
a = 6 轉(zhuǎn)化為2進(jìn)制為 110b = 3 轉(zhuǎn)化為2進(jìn)制為 11
a &b即是 110 與 11
a和b中都為1的位設(shè)為1,位數(shù)不夠的補(bǔ)0.即110 與 011
運(yùn)算結(jié)果010,轉(zhuǎn)化為十進(jìn)制結(jié)果為2
應(yīng)用場(chǎng)景
每個(gè)景點(diǎn)包含很多屬性,例如適合旅游的月份,我們一般的做法可能有兩種:

是增加一個(gè)varchar字段,每個(gè)月份之間用一個(gè)特殊符號(hào)分隔保存,例如:"1,2,22,65,7"
建立一個(gè)關(guān)系表,在這里不能使用1-12的數(shù)字來表示月份,而是使用1,2,4,8,16,32,64,128,512,1024,2048,4096來表示,如果是多個(gè)月份,可以相互組合相加,之后存儲(chǔ)為一個(gè)值。
比如 1,10,12月份,就可以存儲(chǔ)1+512+4096=4609,4096 這個(gè)值。
這個(gè)技巧適用于屬性較少的一對(duì)多的場(chǎng)景,可以存儲(chǔ)1個(gè)或者多個(gè),太多的話還是推薦試用關(guān)系表。常用的屬性有:月份,消息提醒類型,各種有限的類型組合等等。

使用技巧:

-- 添加一個(gè)分類 用 “|”
SELECT (4|2|1); --- = 7

-- 去掉一個(gè)分類,用“^”
SELECT 7 ^ 1;

-- 當(dāng)我們需要查詢某個(gè)月份的景點(diǎn)時(shí),例如查詢3月份的景點(diǎn),可使用以下語句:
SELECT * FROM spots WHERE month & 4 = 4;

-- 當(dāng)設(shè)置某個(gè)景點(diǎn)適合某個(gè)月份時(shí),例如設(shè)置4325的景點(diǎn)適合2月份,可使用下面的語句:

UPDATE spots SET month = month | 2 WHERE id = 4325

-- 當(dāng)取消設(shè)置某個(gè)景點(diǎn)的月份時(shí),可使用下面的語句:
UPDATE spots SETmonth = month ^ 2 WHEREid= 4325

-- 查詢同時(shí)適合多個(gè)月份的數(shù)據(jù),例如需要查詢?cè)O(shè)置了11,12,1月份的景點(diǎn),將其三個(gè)月份對(duì)應(yīng)的數(shù)值加起來,結(jié)果為6145,然后使用這個(gè)數(shù)值進(jìn)行查詢:

SELECT * FROM spots WHERE month & 6145 = 6145

-- 查詢只要適合,1,11,12月份其中一個(gè)月份的景點(diǎn)就行
SELECT * FROM spots WHERE (month & 4096 = 4096) or (month & 2048 = 2048) or (month & 1 = 1)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 運(yùn)算符是處理數(shù)據(jù)的基本方法,用來從現(xiàn)有的值得到新的值。JavaScript 提供了多種運(yùn)算符,本章逐一介紹這些運(yùn)算...
    徵羽kid閱讀 779評(píng)論 0 0
  • 本章將會(huì)介紹 模塊和源文件訪問級(jí)別訪問控制語法自定義類型子類常量、變量、屬性、下標(biāo)構(gòu)造器協(xié)議擴(kuò)展泛型類型別名位運(yùn)算...
    寒橋閱讀 1,004評(píng)論 0 2
  • 高級(jí)運(yùn)算符 文檔地址 作為 基本運(yùn)算符 的補(bǔ)充,Swift 提供了幾個(gè)高級(jí)運(yùn)算符執(zhí)行對(duì)數(shù)傳值進(jìn)行更加復(fù)雜的操作。這...
    hrscy閱讀 913評(píng)論 0 2
  • 這是真的 你如新婚的美貌依舊 而你身后的我 除了抱緊你 守護(hù)你 只有默認(rèn) 身上的鱗片自行脫落 我們似乎不在一條道上...
    XXKY閱讀 318評(píng)論 4 9
  • 今天的目的地是塔里木胡楊林。 走在沙漠公路上,路旁的景色不在是昨日的色彩豐富,換成同一色系,我們車?yán)锓胖钭谑⒌摹?..
    我是李班搬閱讀 402評(píng)論 0 3

友情鏈接更多精彩內(nèi)容