從本文你將了解到什么?
異或運(yùn)算符的使用
或運(yùn)算符的使用
與運(yùn)算符搭配取反運(yùn)算符的使用
二進(jìn)制位運(yùn)算實(shí)戰(zhàn)(1)-開(kāi)發(fā)一個(gè)進(jìn)制轉(zhuǎn)換工具
上篇文章主要講了從ArrayBuffer內(nèi)存中讀取數(shù)據(jù),也即是從bytes數(shù)組中讀取每個(gè)單元格對(duì)應(yīng)的二進(jìn)制值尸饺。
1 toggle功能的實(shí)現(xiàn)
下面我們來(lái)講一下點(diǎn)擊單元格時(shí)值在1和0之間來(lái)回切換是怎么實(shí)現(xiàn)的进统。
每一個(gè)單元格都綁定了點(diǎn)擊事件toggleBit。其實(shí)就是通過(guò)改變bytes數(shù)組的元素值來(lái)改變ArrayBuffer內(nèi)存中的數(shù)據(jù)侵佃。這樣一來(lái)麻昼,通過(guò)Uint32Array讀取同一塊內(nèi)存數(shù)據(jù)后得到的十進(jìn)制數(shù)也會(huì)跟著一起變動(dòng)。
function toggleBit(bit) {? ?
? ? bytes[bit >> 3] = bytes[bit >> 3] ^ (0x1 << (bit & 0x7));? ?
? ? writeBits();
}
我們分析下這段代碼馋辈。
首先代碼中的bit>>3和bit&0x7上篇已經(jīng)講過(guò)抚芦,這里就不再累述了。
“異或”運(yùn)算
異或運(yùn)算符的規(guī)則如下所示:
1^1=0
0^1=1
1^0=1
0^0=0
異或的規(guī)則不太好記, 但是只要記住一句話(huà)"加法不進(jìn)位", 那么一切將會(huì)豁然開(kāi)朗;
在二進(jìn)制中,1 + 1 的結(jié)果是10叉抡。而加法不進(jìn)位就是 1 + 1 = (1)0 = 0尔崔,把進(jìn)位的1去掉,所以1^1的結(jié)果就是0褥民。
那么異或效果可以用于對(duì)位置n的值取反, 實(shí)現(xiàn)toggle功能季春。
0x00000n00 ^ 0x00000100
我們先用左位移運(yùn)算制作一個(gè)"取反器",也即是得到0x00000100消返。
0x1 << 2(n的位置)
如果n是1载弄,0x00000100^0x00000100的得到的就是0x00000000,
如果n是0撵颊,0x00000000^0x00000100的得到的就是0x00000100宇攻;
總是可以對(duì)位置n的值取反。
2 set功能的實(shí)現(xiàn)
如果想要把單元格的值直接置為1或者0倡勇,那么又應(yīng)該怎么實(shí)現(xiàn)呢逞刷。
我們對(duì)鍵盤(pán)的1和0按鍵綁定setBit事件。
function setBit(bit, value) {? ?
? ? if (value === 1) {? ? ?
? ? ? ? bytes[bit >> 3] = bytes[bit >> 3] | (0x1 << (bit & 0x7));? ?
? ? } else if(value === 0) {? ? ?
? ? ? ? bytes[bit >> 3] = bytes[bit >> 3] & ~(0x1 << (bit & 0x7));? ?
? ? }?
? ? writeBits();?}
把單元格設(shè)置為1時(shí)妻熊,會(huì)用到“或”運(yùn)算符夸浅,而把單元格設(shè)置為0時(shí),就要用到“與”運(yùn)算符和“取反”運(yùn)算符扔役。
我們先講講把單元格設(shè)置為1的情況帆喇。
“|按位或”運(yùn)算
按位或運(yùn)算符的規(guī)則如下所示:
1|1=1
0|1=1
1|0=1
0|0=0
比如我們要把位置n的值設(shè)置為1。
0x00000n00 | 0x00000100
照例我們先用左位移運(yùn)算制作一個(gè)"設(shè)置器"厅目,也即是得到0x00000100番枚。
0x1 << 2(n的位置)
如果n是1,0x00000100|0x00000100的得到的就是0x00000100损敷,
如果n是0葫笼,0x00000000|0x00000100的得到的還是0x00000100;
總是可以把位置n的值設(shè)置為1拗馒。
下面再講講把單元格設(shè)置為0的情況路星。
"按位與"和“取反”
來(lái)回顧下與運(yùn)算的規(guī)則:
1&1=1
0&1=0
1&0=0
0&0=0
上篇我們用到與運(yùn)算是為了get值,但現(xiàn)在我們要把位置n的值設(shè)置為0诱桂。
0x00000n00 & ~0x00000100
照例我們先用左位移運(yùn)算制作一個(gè)"置0器"洋丐,也即是先得到0x00000100。然后對(duì)0x00000100取反, 得到0x11111011挥等。
~(0x1 << 2(n的位置))
如果n是1友绝,0x00000100&0x11111011的得到的就是0x00000000,
如果n是0肝劲,0x00000000|0&0x11111011的得到的還是0x00000000迁客;
總是可以把位置n的值設(shè)置為0郭宝。
3 總結(jié)
到這里,關(guān)于這個(gè)二進(jìn)制轉(zhuǎn)換可視化工具的主要方法我們都講了一遍掷漱。只是簡(jiǎn)單地對(duì)bytes數(shù)組的元素進(jìn)行按位get值粘室,set值,取反卜范,居然就把的各種二進(jìn)制位運(yùn)算操作符差不多都用了一遍衔统,是不是感覺(jué)很神奇。
接下來(lái)本公眾號(hào)的“字節(jié)系列”會(huì)持續(xù)更新位運(yùn)算相關(guān)的內(nèi)容海雪,這也是字節(jié)武裝建立 的初衷锦爵。
往期回顧
二進(jìn)制位運(yùn)算實(shí)戰(zhàn)(1)-開(kāi)發(fā)一個(gè)進(jìn)制轉(zhuǎn)換工具
二進(jìn)制、八進(jìn)制喳魏、十進(jìn)制棉浸、十六進(jìn)制數(shù)據(jù)轉(zhuǎn)換
速記卡
當(dāng)n為二進(jìn)制數(shù)時(shí),
與運(yùn)算 0x00000n00 & 0x00000100 讀取n的值刺彩;
異或運(yùn)算 0x00000n00 ^ 0x00000100 對(duì)n取反;
或運(yùn)算 0x00000n00 | 0x00000100 把n設(shè)為1枝恋;
與運(yùn)算+取反運(yùn)算 0x00000n00 & ~0x00000100 把n設(shè)為0创倔。