11 | 二進(jìn)制編碼:“手持兩把錕斤拷,口中疾呼燙燙燙”?

程序 = 算法 + 數(shù)據(jù)結(jié)構(gòu)。對(duì)應(yīng)硬件,算法就是計(jì)算機(jī)指令,數(shù)據(jù)結(jié)構(gòu)就對(duì)應(yīng)二進(jìn)制數(shù)據(jù)。

計(jì)算機(jī)都是用 0 和 1 組成的二進(jìn)制,表示所有信息。指令用到的機(jī)器碼也是二進(jìn)制表示;內(nèi)存里字符串、整數(shù)、浮點(diǎn)數(shù)也是。

快速瀏覽一遍整數(shù)、文本字符串的二進(jìn)制表示。遇到亂碼是怎么回事兒、Unicode 和 UTF-8 之間有什么關(guān)系。

一、理解二進(jìn)制的逢二進(jìn)一

十進(jìn)制整數(shù),都能通過(guò)二進(jìn)制表示出來(lái)。二進(jìn)制對(duì)應(yīng)到十進(jìn)制,比如 0011?=3

把 13 這個(gè)十進(jìn)制數(shù),用短除法轉(zhuǎn)化成二進(jìn)制,=?1101

負(fù)數(shù):最左側(cè)的一位,當(dāng)成是對(duì)應(yīng)的正負(fù)號(hào),比如 0 為正數(shù),1 為負(fù)數(shù)

0011 = +3。補(bǔ)碼1011 = -3。整數(shù)的原碼表示法。缺點(diǎn)1000 代表 0, 0000 也代表 0。

另一種表示法=-5:

最高位1必然是負(fù),最高位 0必然是正。 0000 表示 0,1000 表示 -8。4 位二進(jìn)制數(shù),可從 -8 到 7 這 16 個(gè)整數(shù),不會(huì)浪費(fèi)一位。

?-5 + 1 = -4,-5 + 6 = 1。

字符串的表示,從編碼到數(shù)字,都可用二進(jìn)制表示。

二、ASCII 碼

8 位二進(jìn)制,表示需要所有字符(American Standard Code for Information Interchange,美國(guó)信息交換標(biāo)準(zhǔn)代碼)。

ASCII 碼就好比字典, 128 個(gè)不同數(shù)8 位二進(jìn)制映射128 個(gè)不同字符里。a 在 ASCII 里是第 97 個(gè),二進(jìn)制 0110 0001,十六進(jìn)制 61。A第 65 個(gè),二進(jìn)制0100 0001,十六進(jìn)制41。

ASCII ,9 不是 0000 1001,而是 0011 1001。15 不是用 0000 1111,兩個(gè)字符 1 和 5 連續(xù)放在一起,就是 0011 0001 和 0011 0101,用兩個(gè) 8 位表示。

最大的 32 位整數(shù),2147483647。用整數(shù)只需 32 位。用字符串(多占空間)有 10 個(gè)字符,每個(gè)字符用 8 位的話(huà),需要整整 80 位

存儲(chǔ)數(shù)據(jù)用二進(jìn)制序列化,不是簡(jiǎn)單地把數(shù)據(jù)通過(guò) CSV 或者 JSON進(jìn)行序列化。不管是整數(shù)也好,浮點(diǎn)數(shù)也好,采用二進(jìn)制序列化會(huì)比存儲(chǔ)文本省下不少空間。

ASCII 碼只表示了 128 個(gè)字符不太夠用。于是創(chuàng)建了對(duì)應(yīng)的字符集(Charset)和字符編碼(Character Encoding)。

字符集,字符的集合。比如“中文(《新華字典》里面出現(xiàn)的所有漢字)”就是一個(gè)字符集,“”, Unicode是字符集,150 種語(yǔ)言14 萬(wàn)個(gè)不同的字符。

字符編碼:字符(字符集里)用二進(jìn)制表示的字典。 Unicode可用 UTF-8、UTF-16編碼儲(chǔ)成二進(jìn)制。有了 Unicode可用不止 UTF-8 一種編碼形式,知道編碼規(guī)則,可以正常傳輸、顯示代碼。

同樣文本不同編碼存儲(chǔ)。另一個(gè)程序,不同的編碼方式來(lái)進(jìn)行解碼和展示,就會(huì)亂碼。就像密語(yǔ)通信,用錯(cuò)密碼本不知所云。

搜索郵件歷史出現(xiàn)了“錕斤拷”

想要 Unicode 編碼記錄文本,但這些字符在 Unicode 中并不存在。Unicode 統(tǒng)一記錄為 U+FFFD 編碼。如果用 UTF-8 的格式存儲(chǔ)下來(lái),就是\xef\xbf\xbd。如果連續(xù)兩個(gè)這樣的字符放在一起,\xef\xbf\xbd\xef\xbf\xbd,這個(gè)時(shí)候,如果程序把這個(gè)字符,用 GB2312 的方式進(jìn)行 decode,就會(huì)變成“錕斤拷”。這就好比我們用 GB2312 這本密碼本,去解密別人用 UTF-8 加密的信息,自然沒(méi)辦法讀出有用的信息。

而“燙燙燙”,則是因?yàn)槿绻阌昧?Visual Studio 的調(diào)試器,默認(rèn)使用 MBCS 字符集。“燙”在里面是由 0xCCCC 來(lái)表示的,而 0xCC 又恰好是未初始化的內(nèi)存的賦值。于是,在讀到沒(méi)有賦值的內(nèi)存地址或者變量時(shí),電腦就開(kāi)始大叫“燙燙燙”了。

課后思考

負(fù)數(shù)是原碼表示,應(yīng)該如何處理?如果是補(bǔ)碼表示的呢?請(qǐng)你用二進(jìn)制加法試著算一算,-5+4=-1,通過(guò)原碼和補(bǔ)碼是如何進(jìn)行的?

[-5+4]補(bǔ)=[-5]補(bǔ)+[4]補(bǔ)=[1011+0100]補(bǔ)=[1111]補(bǔ)? 原碼1001

最后編輯于
?著作權(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)容

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