二進(jìn)制位運(yùn)算實(shí)戰(zhàn)(1)-開(kāi)發(fā)一個(gè)進(jìn)制轉(zhuǎn)換工具

從這篇文章你將了解到什么??
ArrayBuffer的作用?
左位移和右位移運(yùn)算的使用?
按位與運(yùn)算的使用


之前介紹了二進(jìn)制相關(guān)的知識(shí)?二進(jìn)制轉(zhuǎn)十進(jìn)制心算大法, 本篇將使用JavaScript開(kāi)發(fā)一個(gè)相關(guān)的可視化工具,實(shí)現(xiàn)十進(jìn)制和二進(jìn)制之間的自動(dòng)轉(zhuǎn)換。

當(dāng)然,醉翁之意不在酒。在開(kāi)發(fā)的過(guò)程中熟悉二進(jìn)制的位運(yùn)算才是本篇的關(guān)注點(diǎn)。

轉(zhuǎn)換工具介紹

下面來(lái)看看這個(gè)可視化工具。

輸入一個(gè)十進(jìn)制的正整數(shù)(32位無(wú)符號(hào)整數(shù)), 我們會(huì)將該數(shù)字的二進(jìn)制展示到一個(gè)表格中。

表格由32個(gè)單元格組成, 因?yàn)?字節(jié)=8字位, 所以單元格按八個(gè)一組來(lái)劃分。

比如, 輸入一個(gè)數(shù)字7, 對(duì)應(yīng)的二進(jìn)制就是111,那么表格就應(yīng)該是下面這樣:

每個(gè)單元格上的二進(jìn)制數(shù)字都可以在0和1之間切換, 對(duì)應(yīng)的也會(huì)計(jì)算出這組二進(jìn)制數(shù)代表的十進(jìn)制數(shù)。

比如, 我們把下圖選中的單元格從0切換為1,那么對(duì)應(yīng)的十進(jìn)制數(shù)也會(huì)跟著變?yōu)?63:

ArrayBuffer介紹

下面我們用數(shù)字263作為例子,講講如何使用位運(yùn)算操作字節(jié)流的方式實(shí)現(xiàn)代碼。

首先,初始化的時(shí)候,我們會(huì)把263這個(gè)數(shù)字放入一個(gè)數(shù)組,然后把這個(gè)數(shù)組轉(zhuǎn)為字節(jié)流存放到ArrayBuffer內(nèi)存當(dāng)中 。

如圖,下方的矩形ArrayBuffer表示一段內(nèi)存,但是我們不能直接操作它。

這時(shí)候我們就要用到JS里的TypedArray來(lái)訪問(wèn)這一段內(nèi)存,MDN把TypedArray稱為“Multiple views on the same data”。

我們可以使用Uint32Array,Uint8Array等等這些“View”來(lái)對(duì)ArrayBuffer內(nèi)存進(jìn)讀寫(xiě)。

這樣一來(lái),我們的“十進(jìn)制展示區(qū)” 和“二進(jìn)制展示區(qū)”都可以從同一塊內(nèi)存中讀取數(shù)據(jù),不用浪費(fèi)另外的數(shù)組空間去存放一大堆的0和1。

另外,在改變“二進(jìn)制展示區(qū)”單元格數(shù)值時(shí),我們可以直接對(duì)ArrayBuffer內(nèi)存中的數(shù)據(jù)進(jìn)行寫(xiě)操作,省去了很多麻煩。

下面請(qǐng)看代碼,我們使用Uint32Array來(lái)表示“十進(jìn)制展示區(qū)” 。

let target = new Uint32Array([263])

將數(shù)組[263]轉(zhuǎn)為字節(jié)流,再讀取為一個(gè)由32位無(wú)符號(hào)字節(jié)組成的數(shù)組,于是變量target賦值的數(shù)組就是[263]。target[0]就是圖中“十進(jìn)制展示區(qū)”的263。

我們使用Uint8Array來(lái)表示“二進(jìn)制展示區(qū)”。?

let bytes = new Uint8Array(target.buffer)

通過(guò)target.buffer可以讀取到內(nèi)存中存放的字節(jié)流,將其讀取為一個(gè)由8位無(wú)符號(hào)字節(jié)組成的數(shù)組,得到的bytes數(shù)組就是[7,1,0,0], 對(duì)應(yīng)的二進(jìn)制數(shù)組就是[0000111,00000001, 00000000, 00000000]。

接下來(lái)我們要將bytes數(shù)組顯示到“二進(jìn)制展示區(qū)”中。

因?yàn)橛?2個(gè)單元格, 我們從第0格遍歷到第31格, 每個(gè)單元格都是通過(guò)getBit方法從bytes數(shù)組中獲取對(duì)應(yīng)的二進(jìn)制數(shù)值。

function writeBits() {? ?

? ? for (var i = 0; i < 32; i++) {? ? ?

? ? ? ? 單元格[i].textContent = getBit(i);? ?

? ? }

}

下面是getBit的具體實(shí)現(xiàn)代碼。

function getBit(bit) {? ?

? ? return bytes[bit >> 3] & (0x1 << (bit & 0x7)) ? 1 : 0;

}

我們一段段來(lái)解釋下。

“bit>>3”分組

“>>”是右位移運(yùn)算符,如果n是整數(shù),那么n>>3效果等同n除以8取除數(shù),可以用于分組;

“bit&7”求余

如果n是整數(shù),n&7效果等同n除以8取余數(shù),可以用于確定n在所屬分組中的位置;

“&”運(yùn)算和“<<”運(yùn)算

我們知道按位與運(yùn)算的規(guī)則是下面這樣:

1&1=1

0&1=0

1&0=0

0&0=0

也即是說(shuō), 如果我們想要知道二進(jìn)制數(shù)字"0100 0n01"中的n是0還是1,可以這樣:

0x01000n01 & 0x00000100

如果結(jié)果等于0,那么n的值就是0;如果結(jié)果大于0,那么n的值就是1。

在按位與運(yùn)算的規(guī)則下,0x00000100就是一個(gè)“取值器”。我們可以通過(guò)左位移運(yùn)算符得到一個(gè)“取值器”。

0x1 << n的位置

把0x0000 0001中的1移動(dòng)到n的位置,也就是0x0000 0100。


例子講解

關(guān)鍵的位運(yùn)算技巧都講完之后,我們用一個(gè)例子來(lái)感受下。

比如我們要得到第2個(gè)單元格(從第0格算起)在bytes數(shù)組[0000111,00000001, 00000000, 00000000]中對(duì)應(yīng)的數(shù)值,具體的過(guò)程就是這樣:

第一步,通過(guò)2>>3=0,可以計(jì)算出第2個(gè)單元格屬于第0組,也就是bytes數(shù)組中下標(biāo)為0的元素。

第二步,通過(guò)2&7=0,可以計(jì)算出第2個(gè)單元格屬于第一組第2個(gè)格(從第0格算起)。

第三步,制作“取值器”,0x1<<2, 得到00000100。

最后,通過(guò)"bytes[0]&取值器"判斷結(jié)果是大于0還是等于0, 就可以得到第2個(gè)單元格的值了。

let res = 0x00000111 & 0x00000100 ? 1 : 0

res的值為1, 也就是第2個(gè)單元格的值為1。是不是很好玩?

未完待續(xù)......



往期回顧

二進(jìn)制、八進(jìn)制、十進(jìn)制、十六進(jìn)制數(shù)據(jù)轉(zhuǎn)換

二進(jìn)制轉(zhuǎn)十進(jìn)制心算大法

?

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 在C語(yǔ)言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來(lái)閱讀 4,035評(píng)論 0 2
  • 進(jìn)制基本概念 什么是進(jìn)制?進(jìn)制是一種計(jì)數(shù)的方式,數(shù)值的表示形式 常見(jiàn)的進(jìn)制十進(jìn)制、二進(jìn)制、八進(jìn)制、十六進(jìn)制 進(jìn)制書(shū)...
    極客江南閱讀 2,187評(píng)論 0 11
  • 原文:Javascript中的二進(jìn)制數(shù)據(jù)類型 最近工作上接手的一個(gè)項(xiàng)目涉及到了圖片的加密壓縮與上傳,也就需要用Ja...
    咖啡豆Bruce閱讀 2,312評(píng)論 0 1
  • 心有猛虎,細(xì)嗅薔薇,白玉無(wú)暇,映照我心。又說(shuō)相愛(ài),相望江湖,無(wú)言以對(duì),癡心絕對(duì)。也說(shuō)有情,十指連心,心疼且傷,憂傷...
    張志強(qiáng)1981閱讀 296評(píng)論 0 0
  • 等我有錢了再娶你 等我有錢了再去環(huán)游世界 等我有錢了再買這件喜歡的衣裳 等我優(yōu)秀了再跟他告白 等… 有好多人都說(shuō)過(guò)...
    二姐伊人閱讀 437評(píng)論 3 2

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