计算机里FC方式,【计算机基础】在0和1的世界里来来回回
事物的正反兩面被哲學(xué)家討論了幾千年。計(jì)算機(jī)里的0和1也照舊玩出了各種花樣。
二進(jìn)制數(shù) VS 十進(jìn)制數(shù)
本小節(jié)講二進(jìn)制寫(xiě)法,以及到十進(jìn)制的轉(zhuǎn)換方法,如果已熟悉這些內(nèi)容可以直接跳到下一小節(jié)。
我們生活在一個(gè)十進(jìn)制的世界中。10個(gè)一毛就是一塊,10個(gè)一兩就是一斤。在數(shù)學(xué)上有滿十進(jìn)一或借一當(dāng)十。
十進(jìn)制數(shù)的基數(shù)就是0到9,因此所有的十進(jìn)制數(shù)都是由0到9這九個(gè)數(shù)字組合出來(lái)的。
計(jì)算機(jī)底層處理的都是二進(jìn)制數(shù),可以對(duì)比十進(jìn)制數(shù)來(lái)看看二進(jìn)制數(shù)的特點(diǎn):
滿二進(jìn)一或借一當(dāng)二,基數(shù)是0和1,就是說(shuō)所有的二進(jìn)制數(shù)都是由0和1這兩個(gè)數(shù)字組合出來(lái)的。
就十進(jìn)制而言,十個(gè)1已經(jīng)達(dá)到“滿十”的條件,所以要“進(jìn)一”,于是就是10,這是個(gè)十進(jìn)制數(shù),它的值就是十,因?yàn)槭鞘畟€(gè)1合在了一起。
就二進(jìn)制而言,兩個(gè)1已經(jīng)達(dá)到“滿二”的條件,所以要“進(jìn)一”,于是就是10,這是個(gè)二進(jìn)制數(shù),它的值就是二,因?yàn)槭莾蓚€(gè)1合在了一起。
如果剛剛這個(gè)明白了,結(jié)合十進(jìn)制和二進(jìn)制的特點(diǎn),接下來(lái)就非常容易理解了:
1 + 1 = 2 -> 10。
1 + 1 + 1 = 3 = 2 + 1 -> 10 + 1 -> 11。
1 + 1 + 1 + 1 = 4 = 3 + 1 -> 11 + 1 -> 100。
照此類(lèi)推,列出幾個(gè)十進(jìn)制和對(duì)應(yīng)的二進(jìn)制:
0 -> 000
1 -> 001
2 -> 010
3 -> 011
4 -> 100
5 -> 101
接下來(lái)嘗試找出二進(jìn)制和十進(jìn)制之間的換算關(guān)系。
首先,十進(jìn)制數(shù)是怎么使用每個(gè)位置上的數(shù)字表示出來(lái)的呢?相信所有人都很熟悉。如下面示例:
123 -> 100 + 20 + 3
123 -> 1 100 + 2 10 + 3 * 1
因十進(jìn)制滿十進(jìn)一,要想辦法和十聯(lián)系起來(lái),100就是10的2次方,10是10的1次方,1是10的0次方,于是:
123 -> 1 10 ^ 2 + 2 10 ^ 1 + 3 * 10 ^ 0;
進(jìn)而,我們發(fā)現(xiàn)百位的位置是3,但次方卻是2,正好是3減去1,十位的位置是2,但次方是1,正好是2減去1,個(gè)位就是1減去1,也就是0次方了。
于是,這個(gè)公式就出來(lái)了,太簡(jiǎn)單了,大家都知道,就不寫(xiě)了。
然后,我們把這個(gè)“套路”搬到二進(jìn)制數(shù)里試試看吧,只不過(guò)二進(jìn)制數(shù)是滿二進(jìn)一,因此要用2的次方。
000 -> 0 2 ^ 2 + 0 2 ^ 1 + 0 2 ^ 0
000 -> 0 4 + 0 2 + 0 1 -> 0
000 -> 0
001 -> 0 2 ^ 2 + 0 2 ^ 1 + 1 2 ^ 0
001 -> 0 4 + 0 2 + 1 1 -> 1
001 -> 1
010 -> 0 2 ^ 2 + 1 2 ^ 1 + 0 2 ^ 0
010 -> 0 4 + 1 2 + 0 1 -> 2
010 -> 2
011 -> 0 2 ^ 2 + 1 2 ^ 1 + 1 2 ^ 0
011 -> 0 4 + 1 2 + 1 1 -> 3
011 -> 3
100 -> 1 2 ^ 2 + 0 2 ^ 1 + 0 2 ^ 0
100 -> 1 4 + 0 2 + 0 1 -> 4
100 -> 4
101 -> 1 2 ^ 2 + 0 2 ^ 1 + 1 2 ^ 0
101 -> 1 4 + 0 2 + 1 1 -> 5
101 -> 5
我們發(fā)現(xiàn)算出來(lái)的正好都是其對(duì)應(yīng)的十進(jìn)制數(shù)。這是巧合嗎?當(dāng)然不是了。其實(shí):
這就是二進(jìn)制數(shù)向十進(jìn)制數(shù)的轉(zhuǎn)化方法。
我們也可以模仿數(shù)學(xué),推導(dǎo)出個(gè)公式來(lái):
d = b(n) + b(n - 1) + ... + b(1) + b(0)
b(n) = a * 2 ^ n,(a = {0、1},n >= 0)
就是把二進(jìn)制數(shù)的每一位轉(zhuǎn)化為十進(jìn)制數(shù),再加起來(lái)即可。
負(fù)數(shù)的二進(jìn)制 VS 正數(shù)的二進(jìn)制
上一小節(jié)都是以正數(shù)舉例。除了正數(shù)之外,還有負(fù)數(shù)和零。
因此,計(jì)算機(jī)界規(guī)定,在需要考慮正負(fù)的時(shí)候,二進(jìn)制的最高位就是符號(hào)位。
即這個(gè)位置上的0或1是用來(lái)表示數(shù)值符號(hào)的,而非用來(lái)計(jì)算數(shù)值的,且規(guī)定:
0表示為正數(shù),1表示為負(fù)數(shù)。
那0既不是正數(shù)也不是負(fù)數(shù),該怎么表示呢?把0的二進(jìn)制輸出一下:
0 -> 00000000
發(fā)現(xiàn)全是0,最高位也是0,因此0是一種特殊情況。
接下來(lái)開(kāi)始講解負(fù)數(shù)的二進(jìn)制表示,保證看完后有一種“恍然大悟”的感覺(jué)(如果沒(méi)有,那我也沒(méi)辦法),哈哈。
長(zhǎng)期以來(lái)受數(shù)學(xué)的影響,要把一個(gè)正數(shù)變成對(duì)應(yīng)的負(fù)數(shù),只需在前面加一個(gè)負(fù)號(hào)“-”即可。
基于此,再結(jié)合上面計(jì)算機(jī)界的規(guī)定,我們很容易想當(dāng)然的認(rèn)為,一個(gè)正數(shù)只要把它的最高位由0設(shè)置為1就變成了對(duì)應(yīng)的負(fù)數(shù),像這樣:
因?yàn)?1的二進(jìn)制是,00000001
所以-1的二進(jìn)制是,10000001
鄭重聲明,這是錯(cuò)誤的。繼續(xù)往下看就知道原因了。
首先會(huì)從官方的角度給出正確結(jié)果(裝b用的),然后會(huì)從個(gè)人的角度給出正確結(jié)果(恍然大悟用的)。
站在官方(或?qū)W術(shù))的角度,先引入三個(gè)概念:
原碼:把一個(gè)數(shù)當(dāng)作正數(shù)(負(fù)數(shù)的話把負(fù)號(hào)去掉即可),它的二進(jìn)制表示就叫原碼。
反碼:把原碼中的0變成1、1變成0(即0和1對(duì)調(diào)),所得到的就叫反碼。
補(bǔ)碼:反碼加上1,所得到的就叫補(bǔ)碼。
(這是學(xué)術(shù)界的名詞,不要糾結(jié)為什么,記住即可)
還以-1為例,進(jìn)行一下推導(dǎo):
把 -1當(dāng)作 1,原碼是,00000001
把0和1對(duì)調(diào),反碼是,11111110
然后加上 1, 補(bǔ)碼是,11111111
于是-1的補(bǔ)碼是,11111111。再使用類(lèi)庫(kù)中的工具類(lèi)輸出一下-1的二進(jìn)制形式,發(fā)現(xiàn)竟然還是它。這也不是巧合,因?yàn)?#xff1a;
在計(jì)算機(jī)中,負(fù)數(shù)的二進(jìn)制就是用它的補(bǔ)碼形式表示的。
這就是官方的說(shuō)法,總喜歡整一些名詞來(lái)把大家弄得一懵一懵的。
下面就站在個(gè)人角度,以最“土鱉”的方式來(lái)揭秘。
首先,-1的二進(jìn)制是11111111這種形式一下子確實(shí)不容易接受。
反倒是把-1的二進(jìn)制假設(shè)為10000001更容易讓人接受,因?yàn)榕c它對(duì)應(yīng)的1的二進(jìn)制是00000001。
這樣從數(shù)值的大小上(即絕對(duì)值)來(lái)看都是1,從符號(hào)上來(lái)看一個(gè)是1一個(gè)是0恰好表示一負(fù)一正,簡(jiǎn)直“堪稱(chēng)完美”。
那為什么這種假設(shè)的形式卻是錯(cuò)的呢?
因?yàn)閺氖M(jìn)制的角度來(lái)說(shuō),1 + (-1) = 0。
再按假設(shè)的形式把它們轉(zhuǎn)換為對(duì)應(yīng)的二進(jìn)制,
00000001 + 10000001 = 10000010,
依照假設(shè),這個(gè)結(jié)果的值是-2。
可見(jiàn),一個(gè)是0,一個(gè)是-2,這顯然是不對(duì)的。雖然是采用不同的進(jìn)制,但結(jié)果應(yīng)該是一樣的才對(duì)。
很顯然,二進(jìn)制這種計(jì)算方式的結(jié)果是錯(cuò)誤的,錯(cuò)誤的原因是,-1的二進(jìn)制形式不能按照我們假設(shè)的那種方式進(jìn)行。
那-1的二進(jìn)制應(yīng)該按什么邏輯去計(jì)算呢?相信你已經(jīng)猜到了。
因?yàn)?#xff0c;-1 = 0 - 1,所以,
-1 = 00000000 - 00000001 = 11111111。
因此,-1的二進(jìn)制就是11111111。這樣一來(lái),
-1 + 1 = 11111111 + 00000001 = 00000000 = 0。
這樣是不是一下子就明白了-1的二進(jìn)制為什么全是1了。因?yàn)檫@種形式滿足了數(shù)值計(jì)算上的需要。
同理可以算下-2的二進(jìn)制,
-2 = -1 - 1 = 11111111 - 00000001 = 11111110。
其實(shí)原碼/反碼/補(bǔ)碼之間的轉(zhuǎn)換關(guān)系也是基于正數(shù)和負(fù)數(shù)的和為零而設(shè)計(jì)出來(lái)的。仔細(xì)體會(huì)下便可明白。
可見(jiàn),官方角度和個(gè)人角度的本質(zhì)是一樣的,只不過(guò)一個(gè)陽(yáng)春白雪、一個(gè)下里巴人。
這讓我想起來(lái)了雅和俗,很多人標(biāo)榜著追求雅,其實(shí)他們需要的恰恰是俗。
下面是一些正數(shù)和對(duì)應(yīng)負(fù)數(shù)的例子:
2,00000010
-2,11111110
5,00000101
-5,11111011
127,01111111
-127,10000001
可以看到十進(jìn)制數(shù)的和是0,對(duì)應(yīng)二進(jìn)制數(shù)的和也是0。
這才是正確的負(fù)數(shù)的二進(jìn)制表示,雖然看起來(lái)的跟感覺(jué)起來(lái)的不太一樣。
就十進(jìn)制來(lái)說(shuō),當(dāng)位數(shù)固定后,所有位置上都是9時(shí),數(shù)值達(dá)到最大,如最大的四位數(shù)就是9999。
對(duì)于二進(jìn)制來(lái)說(shuō)也是一樣的,除去最高位0表示正數(shù)外,剩余的位置全部是1時(shí),數(shù)值達(dá)到最大,如最大的八位數(shù)就是01111111,對(duì)應(yīng)的十進(jìn)制數(shù)就是127。
一個(gè)字節(jié)的長(zhǎng)度就是8位,因此一個(gè)字節(jié)能表示的最大正數(shù)就是127,即一個(gè)0帶著7個(gè)1,這是正向的邊界值了。
通過(guò)觀察負(fù)數(shù),除去最高位1表示負(fù)數(shù)外,后面7位全部為0時(shí),應(yīng)該是負(fù)數(shù)的最小值,即一個(gè)1帶著7個(gè)0,對(duì)應(yīng)的十進(jìn)制數(shù)是-128,這是負(fù)向的邊界值了。
而且正向和負(fù)向的邊界值是有關(guān)系的,你發(fā)現(xiàn)了嗎?就是正向邊界值加上1之后的相反數(shù)即為負(fù)向邊界值。
二進(jìn)制的常規(guī)操作
這些內(nèi)容應(yīng)該都非常熟悉了,瞄一眼即可。
位操作
與(and):
1 & 1 -> 1
0 & 1 -> 0
1 & 0 -> 0
0 & 0 -> 0
或(or):
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
非(not):
~0 -> 1
~1 -> 0
異或(xor):
0 ^ 1 -> 1
1 ^ 0 -> 1
0 ^ 0 -> 0
1 ^ 1 -> 0
移位操作
左移(<
左邊丟棄(符號(hào)位照樣丟棄),右邊補(bǔ)0。
移完后,最高位是0為正數(shù),是1為負(fù)數(shù)。
左移一位相當(dāng)于乘2,二位相當(dāng)于乘4,以此類(lèi)推。
當(dāng)左移一個(gè)周期時(shí),回到原點(diǎn)。即相當(dāng)于不移。
超過(guò)一個(gè)周期后,把周期部分除掉,移動(dòng)剩下的。
移動(dòng)的位數(shù)和二進(jìn)制本身的長(zhǎng)度相等時(shí),稱(chēng)為周期。如8位長(zhǎng)度的二進(jìn)制移動(dòng)8位。
右移(>>):
右邊丟棄,正數(shù)左邊補(bǔ)0,負(fù)數(shù)左邊補(bǔ)1。
右移一位相當(dāng)于除2,二位相當(dāng)于除4,以此類(lèi)推。
在四舍五入時(shí),正數(shù)選擇舍,負(fù)數(shù)選擇入。
正數(shù)右移從都丟棄完開(kāi)始往后數(shù)值都是0,因?yàn)閺淖筮呇a(bǔ)進(jìn)來(lái)的都是0,直到到達(dá)一個(gè)周期時(shí),回到原點(diǎn),即回到原來(lái)的數(shù)值。相當(dāng)于不移。
負(fù)數(shù)右移從都丟棄完開(kāi)始往后數(shù)值都是-1,因?yàn)閺淖筮呇a(bǔ)進(jìn)來(lái)的都是1,直到到達(dá)一個(gè)周期時(shí),回到原點(diǎn),即回到原來(lái)的數(shù)值。相當(dāng)于不移。
超過(guò)一個(gè)周期后,把周期部分除掉,移動(dòng)剩下的。
無(wú)符號(hào)右移(>>>):
右邊丟棄,無(wú)論正數(shù)還是負(fù)數(shù)左邊都是補(bǔ)0。
因此對(duì)于正數(shù)來(lái)說(shuō)和右移(>>)沒(méi)有什么差別。
對(duì)于負(fù)數(shù)來(lái)說(shuō)會(huì)變成正數(shù),就是使用原來(lái)的補(bǔ)碼形式,丟棄右邊后當(dāng)作正數(shù)來(lái)計(jì)算。
為什么沒(méi)有無(wú)符號(hào)左移呢?
因?yàn)樽笠茣r(shí),是在右邊補(bǔ)0的,而符號(hào)位是在最左邊的,右邊補(bǔ)的東西是影響不到它的。
可能有人會(huì)想,到達(dá)一個(gè)周期后,再移動(dòng)的話不就影響到了嘛,哈哈,在一個(gè)周期的時(shí)候是會(huì)進(jìn)行歸零的。
二進(jìn)制的伸/縮
以下內(nèi)容都假定高位字節(jié)在前低位字節(jié)在后的順序。
伸:
如把一個(gè)字節(jié)伸長(zhǎng)為兩個(gè)字節(jié),則需要填充高位字節(jié)。(等于把byte類(lèi)型賦給short類(lèi)型)
其實(shí)就是這個(gè)字節(jié)原樣不動(dòng),在它的左邊再接上一個(gè)字節(jié)。
此時(shí)符號(hào)和數(shù)值大小都保持不變。
正數(shù)符號(hào)位是0,伸長(zhǎng)時(shí)高位字節(jié)填充0。
00000110 -> 00000000,00000110
負(fù)數(shù)符號(hào)位是1,伸長(zhǎng)時(shí)高位字節(jié)填充1。
11111010 -> 11111111,11111010
縮:
把兩個(gè)字節(jié)壓縮為一個(gè)字節(jié),需要截?cái)喔呶蛔止?jié)。(等于把short類(lèi)型強(qiáng)制賦給byte類(lèi)型)
其實(shí)就是左邊字節(jié)直接丟棄,右邊字節(jié)原樣不動(dòng)的保留。
此時(shí)符號(hào)和數(shù)值大小都可能發(fā)生改變。
如果壓縮后的字節(jié)仍能放得下這個(gè)數(shù),則符號(hào)和數(shù)值大小都保持不變。
具體來(lái)說(shuō)就是如果正數(shù)的高位字節(jié)全是0,同時(shí)低位字節(jié)的最高位也是0。或負(fù)數(shù)的高位字節(jié)全是1,同時(shí)低位字節(jié)的最高位也是1。截?cái)喔呶蛔止?jié)不會(huì)對(duì)數(shù)造成影響。
00000000,00001100 -> 00001100
11111111,11110011 -> 11110011
如果壓縮后的字節(jié)放不下這個(gè)數(shù),則數(shù)值大小一定改變。
具體說(shuō)就是如果正數(shù)的高位字節(jié)不全是0,負(fù)數(shù)的高位字節(jié)不全是1,截?cái)喔呶蛔止?jié)肯定會(huì)對(duì)數(shù)的大小造成影響。
至于符號(hào)是否改變?nèi)Q于原符號(hào)位和壓縮后的符號(hào)位是否一樣。
例如,壓縮后大小發(fā)生改變,符號(hào)不變的如下:
00001000,00000011 壓縮為 00000011,還是正數(shù)
11011111,11111101 壓縮為 11111101,還是負(fù)數(shù)
例如,壓縮后大小和符號(hào)都發(fā)生改變的如下:
00001000,10000011 壓縮為 10000011,正數(shù)變負(fù)數(shù)。
11011111,01111101 壓縮為 01111101,負(fù)數(shù)變正數(shù)。
整數(shù)的序列化和反序列化
一般來(lái)說(shuō),一個(gè)int類(lèi)型是由四個(gè)字節(jié)組成的,在序列化時(shí),需要將這四個(gè)字節(jié)一一拆開(kāi),按順序放入到一個(gè)字節(jié)數(shù)組中。
在反序列化時(shí),從字節(jié)數(shù)組中拿出這四個(gè)字節(jié),把它們按順序接在一起,重新解釋為一個(gè)int類(lèi)型的數(shù)字,結(jié)果應(yīng)該保持不變。
在序列化時(shí),主要用到的就是移位和壓縮。
首先將要拆出來(lái)的字節(jié)移到最低位(即最右邊),然后強(qiáng)制轉(zhuǎn)換為byte類(lèi)型即可。
假如有一個(gè)int類(lèi)型數(shù)字如下:
11111001,11001100,10100000,10111001
第一步,右移24位并只保留最低八位,
byte b3 = (byte)(i >> 24);
11111111,11111111,11111111,11111001
11111001
第二步,右移16位并只保留最低八位,
byte b2 = (byte)(i >> 16);
11111111,11111111,11111001,11001100
11001100
第三步,右移8位并只保留最低八位,
byte b1 = (byte)(i >> 8);
11111111,11111001,11001100,10100000
10100000
第三步,右移0位并只保留最低八位,
byte b0 = (byte)(i >> 0);
11111001,11001100,10100000,10111001
10111001
這樣就產(chǎn)生了四個(gè)字節(jié),把它們放入字節(jié)數(shù)組就可以了。
byte[] bytes = new byte[]{b3, b2, b1, b0};
在反序列化時(shí),主要用到的就是伸長(zhǎng)和移位。
首先從字節(jié)數(shù)組中拿出一個(gè)字節(jié),將它轉(zhuǎn)換為int類(lèi)型,然后再處理符號(hào)問(wèn)題,接著再左移到適合位置。
第一步:
取出第一個(gè)字節(jié),
11111001
然后伸長(zhǎng)為int,
11111111,11111111,11111111,11111001
因?yàn)樗姆?hào)位就表示了原來(lái)整數(shù)的符號(hào)位,因此不用處理符號(hào),直接左移24位,
11111001,00000000,00000000,00000000
第二步:
取出第二個(gè)字節(jié),
11001100
然后伸長(zhǎng)為int,
11111111,11111111,11111111,11001100
因?yàn)樗姆?hào)位是處在原來(lái)整數(shù)的中間位置的,因此它不表示符號(hào)而表示數(shù)值,需要處理符號(hào)位,就是執(zhí)行一個(gè)與操作,
如下,上面兩行相與得到第三行,
11111111,11111111,11111111,11001100
00000000,00000000,00000000,11111111
00000000,00000000,00000000,11001100
接著左移16位
00000000,11001100,00000000,00000000
第三步,
取出第三個(gè)字節(jié),
10100000
然后伸長(zhǎng)為int,
11111111,11111111,11111111,10100000
然后處理符號(hào)位,
00000000,00000000,00000000,10100000
接著左移8位,
00000000,00000000,10100000,00000000
第四步,
取出第四個(gè)字節(jié),
10111001
然后伸長(zhǎng)為int,
11111111,11111111,11111111,10111001
然后處理符號(hào)位,
00000000,00000000,00000000,10111001
接著左移0位,
00000000,00000000,00000000,10111001
這樣四步就產(chǎn)生了四個(gè)結(jié)果,如下:
11111001,00000000,00000000,00000000
00000000,11001100,00000000,00000000
00000000,00000000,10100000,00000000
00000000,00000000,00000000,10111001
可以看到四個(gè)字節(jié)都已經(jīng)位于自己應(yīng)該在的位置上了。
最后來(lái)一個(gè)加法操作就可以了,其實(shí)或操作也是可以的。
i = i4 + i3 + i2 + i0
i = i4 | i3 | i2 | i0
這樣我們就將字節(jié)數(shù)組中的四個(gè)字節(jié)合成為一個(gè)int類(lèi)型的數(shù)字了。
模擬實(shí)現(xiàn)無(wú)符號(hào)數(shù)
無(wú)符號(hào)數(shù),即最高位不是符號(hào)位而是數(shù)值位。
有一些語(yǔ)言如Java不支持無(wú)符號(hào)數(shù),所以需要使用有符號(hào)數(shù)來(lái)模擬實(shí)現(xiàn)。
因?yàn)橥粋€(gè)類(lèi)型作為無(wú)符號(hào)數(shù)時(shí)的范圍會(huì)大于作為有符號(hào)數(shù)時(shí)的范圍,因此會(huì)用更長(zhǎng)的類(lèi)型存放短類(lèi)型的無(wú)符號(hào)數(shù)。
如byte類(lèi)型是一個(gè)字節(jié),作為有符號(hào)數(shù)時(shí)范圍是-128到127,作為無(wú)符號(hào)數(shù)時(shí)范圍是0到255,所以至少需要用兩個(gè)字節(jié)的short類(lèi)型來(lái)存放。
處理方法很簡(jiǎn)單,只需兩步,伸長(zhǎng)和處理符號(hào)位。
假如有一個(gè)字節(jié)是,10101011,這是一個(gè)byte類(lèi)型的負(fù)數(shù)。
第一步,伸長(zhǎng),此時(shí)變成兩個(gè)字節(jié)了,但還是一個(gè)負(fù)數(shù)
11111111,10101011
第二步,處理符號(hào),即執(zhí)行一個(gè)與操作
11111111,10101011
00000000,11111111
00000000,10101011
這就已經(jīng)處理完了,由一個(gè)字節(jié)的負(fù)數(shù)變成了兩個(gè)字節(jié)的正數(shù)。
其實(shí)就是將原來(lái)的字節(jié)前面(即左邊)接上去一個(gè)全0的字節(jié)。
當(dāng)byte作為無(wú)符號(hào)數(shù),取到最大值255時(shí),二進(jìn)制是這樣的
00000000,11111111
此時(shí)也只不過(guò)才剛剛使用完低位置。
因此使用長(zhǎng)類(lèi)型表示短類(lèi)型的無(wú)符號(hào)數(shù),對(duì)長(zhǎng)類(lèi)型的字節(jié)利用效率最高也就百分之五十了。
對(duì)于這種情況,在序列化時(shí),其實(shí)只需寫(xiě)入低半部分的字節(jié)即可。
在反序列化時(shí),一是要用長(zhǎng)類(lèi)型來(lái)承接,二是所有字節(jié)都要處理符號(hào),作為無(wú)符號(hào)數(shù)對(duì)待。
PS:這次算是認(rèn)認(rèn)真真的復(fù)習(xí)了十年前在大學(xué)里的專(zhuān)業(yè)課基礎(chǔ)知識(shí)。
其實(shí)我是在寫(xiě)“品Spring”系列文章時(shí),發(fā)現(xiàn)最好能熟悉Java的字節(jié)碼(.class)文件內(nèi)部結(jié)構(gòu)。
在嘗試解析字節(jié)碼文件時(shí),發(fā)現(xiàn)它里面存儲(chǔ)的都是無(wú)符號(hào)數(shù),所以需要寫(xiě)一個(gè)把字節(jié)數(shù)組反序列化為無(wú)符號(hào)數(shù)的工具。
在寫(xiě)工具時(shí)看了一點(diǎn)JDK相關(guān)部分的源碼,就索性把二進(jìn)制的基本知識(shí)和操作都親自寫(xiě)代碼測(cè)試了一遍。
于是就整理出了這篇文章,呵呵。
(END)
總結(jié)
以上是生活随笔為你收集整理的计算机里FC方式,【计算机基础】在0和1的世界里来来回回的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 刀片服务器 如何增加硬盘,IBM为刀片服
- 下一篇: java webstock 在线直播_在