二進(jìn)制位運(yùn)算實(shí)戰(zhàn)(2)-異或,按位或,按位與,取反

從本文你將了解到什么?

異或運(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ī)則不太好記, 但是只要記住一句話"加法不進(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ì)鍵盤的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)換

二進(jìn)制轉(zhuǎn)十進(jì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。

?著作權(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)容

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