偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

關(guān)于二進(jìn)制表示和補(bǔ)碼計(jì)算的來(lái)龍去脈,入門看了秒懂

開發(fā)
這篇文章,我們探討了計(jì)算機(jī)系統(tǒng)的軟件基石:二進(jìn)制系統(tǒng),主要的目的是幫助你理解二進(jìn)制的表示、計(jì)算方式。

[[391784]]

 一、前言

計(jì)算機(jī)最喜歡的數(shù)字就是 0 和 1,在 CPU 的世界中,它只認(rèn)識(shí)這兩個(gè)數(shù)字,即使是強(qiáng)大的操作系統(tǒng),也都是由 0 和 1 組成的。

作為一名軟件開發(fā)者,入門學(xué)習(xí)的內(nèi)容可能就是認(rèn)識(shí)這 2 個(gè)既簡(jiǎn)單、又強(qiáng)大的數(shù)字。但是大部分人,對(duì)于二進(jìn)制、二進(jìn)制計(jì)算、原碼、反碼以及補(bǔ)碼的認(rèn)識(shí),仍處于機(jī)械的強(qiáng)制記憶階段。尤其是對(duì)一些編碼和計(jì)算,仍然處于模糊的認(rèn)識(shí)階段,例如:

  1. CPU 是如何表示負(fù)數(shù)的?
  2. 為什么補(bǔ)碼可以用來(lái)表示負(fù)數(shù)?
  3. 一個(gè) 8 位的二進(jìn)制數(shù),最小值為什么是 -128,而不是 -127?
  4. CPU 中的加法器,為什么可以連同符號(hào)位一起運(yùn)算?

這篇文章我們就來(lái)聊聊這個(gè)最最基礎(chǔ)的內(nèi)容,幫助你來(lái)理解二進(jìn)制計(jì)算的相關(guān)內(nèi)容,看完這篇文章之后,不僅知其然,更能知其所以然!

PS: 這里有點(diǎn)高調(diào)了,最終的所以然部分,應(yīng)該涉及到數(shù)學(xué)證明這一層次了,本文并不會(huì)涉及到求證過(guò)程。

二、從十進(jìn)制到二進(jìn)制

1. 十進(jìn)制

作為數(shù)學(xué)計(jì)算能力強(qiáng)大的中國(guó),10 以內(nèi)的加減法,應(yīng)該是在幼兒園階段就完成了。如果你不屬于這個(gè)范圍,說(shuō)明你上的是假幼兒園。

我們來(lái)快速?gòu)?fù)習(xí)一下關(guān)于十進(jìn)制運(yùn)算的一些基本知識(shí):

  1. 每一個(gè)數(shù)位上包括的數(shù)字為 0 到 9;
  2. 每一個(gè)數(shù)位上的數(shù),是它右側(cè)數(shù)位的 10 倍;
  3. 兩個(gè)數(shù)相加時(shí),相同數(shù)位上的數(shù)相加之和如果大于等于 10,就向前進(jìn) 1 位,即:滿十進(jìn)一;

具體來(lái)看就是:

  1. 從右數(shù)第一個(gè)位數(shù)(個(gè)位)上的數(shù)字代表多少個(gè) 1;
  2. 從右數(shù)第二個(gè)位數(shù)(十位)上的數(shù)字代表多少個(gè) 10;
  3. 從右數(shù)第三個(gè)位數(shù)(百位)上的數(shù)字代表多少個(gè) 100;
  4. 從右數(shù)第四個(gè)位數(shù)(千位)上的數(shù)字代表多少個(gè) 1000;

十進(jìn)制的數(shù),可以使用后綴字母 D 來(lái)表示,也可以省略。例如:十進(jìn)制的 1234 這個(gè)數(shù)字,個(gè)位上的數(shù)是 4, 十位上的數(shù)是 3, 百位上的數(shù)是 2,千位上的數(shù)是 1(一般是從最右側(cè)的個(gè)位說(shuō)起),每一個(gè)數(shù)位上的數(shù)比它右側(cè)大十倍。如下圖:

 

十進(jìn)制數(shù)據(jù),也稱作基于十的表示法。

2. 二進(jìn)制

那么對(duì)于二進(jìn)制呢?直接套用上面十進(jìn)制的概念,然后把 10 換成 2 即可(目前先忽略符號(hào)位):

  1. 每一個(gè)數(shù)位上包括的數(shù)字為 0 和 1;
  2. 每一個(gè)數(shù)位上的數(shù),是它右側(cè)數(shù)位的 2 倍;
  3. 兩個(gè)數(shù)相加時(shí),相同數(shù)位上的數(shù)相加之和如果大于等于 2,就向前進(jìn) 1 位,即:滿二進(jìn)一;

具體來(lái)看就是:

  1. 從右數(shù)第一個(gè)位數(shù)上的數(shù)字代表多少個(gè) 1;
  2. 從右數(shù)第二個(gè)位數(shù)上的數(shù)字代表多少個(gè) 2;
  3. 從右數(shù)第三個(gè)位數(shù)上的數(shù)字代表多少個(gè) 4;
  4. 從右數(shù)第四個(gè)位數(shù)上的數(shù)字代表多少個(gè) 8;

記住幾個(gè)重點(diǎn):二進(jìn)制數(shù)中只包含 0 和 1 兩個(gè)數(shù)字,在相加時(shí)滿二進(jìn)一。

在十進(jìn)制中,每一個(gè)數(shù)位我們給它進(jìn)行了專門的命名(個(gè)位、十位、百位...),但是二進(jìn)制沒(méi)有類似的命名。

二進(jìn)制的數(shù),使用后綴字母 B 來(lái)表示,例如:二進(jìn)制的 1111B 這個(gè)數(shù)字,用圖來(lái)表示權(quán)重如下:

換算成十進(jìn)制數(shù)就是 15(1 * 8 + 1 * 4 + 1 * 2 + 1 * 1 = 15)。

在二進(jìn)制中,每一位稱為一個(gè)比特(bit),如果用 8 個(gè) bit 來(lái)表示一個(gè)二進(jìn)制數(shù),最小值是 0000_00000,最大值是 1111_1111;

如果用 16 個(gè) bit 來(lái)表示一個(gè)二進(jìn)制數(shù),最小值是 0000_0000_0000_0000,最大值是 1111_1111_1111_1111。(為了便于觀察,每 4 個(gè) bit 之間,加上了分隔符)

在早期的計(jì)算機(jī)中,8 位的處理器很常見,于是就給它一個(gè)專門的名字:字節(jié)(Byte)。16 位的二進(jìn)制數(shù)就是 2 個(gè)字節(jié),也稱作:字(Word)。

3. 擴(kuò)展到十六進(jìn)制

原理還是相同的:直接把十進(jìn)制中的 10 換成 16 即可:

  1. 每一個(gè)數(shù)位上包括的數(shù)字為 0 到 9,A 到 F;
  2. 每一個(gè)數(shù)位上的數(shù),是它右側(cè)數(shù)位的 16 倍;
  3. 兩個(gè)數(shù)相加時(shí),相同數(shù)位上的數(shù)相加之和如果大于等于 16,就向前進(jìn) 1 位,即:滿十六進(jìn)一;

具體來(lái)看就是:

  1. 從右數(shù)第一個(gè)位數(shù)上的數(shù)字代表多少個(gè) 1;
  2. 從右數(shù)第二個(gè)位數(shù)上的數(shù)字代表多少個(gè) 16;
  3. 從右數(shù)第三個(gè)位數(shù)上的數(shù)字代表多少個(gè) 256;
  4. 從右數(shù)第四個(gè)位數(shù)上的數(shù)字代表多少個(gè) 4096;

在十六進(jìn)制中,需要十六個(gè)數(shù)字來(lái)表示 0 到 15 這些數(shù)字,0 到 9 比較好處理,但是從 10 到 15,我們就需要找一些記號(hào)來(lái)表示,于是人們就想到用 A,B,C,D,E,F 這幾個(gè)字母來(lái)分別表示 10 到 15 這個(gè) 6 個(gè)數(shù)字。

十六進(jìn)制數(shù)據(jù),使用后綴字母 H 來(lái)表示,有些場(chǎng)合也可以使用前綴 0x 來(lái)表示,本質(zhì)上沒(méi)有區(qū)別。例如:十六進(jìn)制數(shù)字 1A2BH(或者寫作 0x1A2B),每一個(gè)數(shù)位上的權(quán)重如圖:

換算成十進(jìn)制數(shù)就是 6699(1 * 4096 + 10 * 256 + 2 * 16 + 11 * 1 = 6699)。

4. 擴(kuò)展到任意進(jìn)制

原理仍然相同:直接把十進(jìn)制中的 10 換成目標(biāo)進(jìn)制,例如 5 進(jìn)制

  1. 每一個(gè)數(shù)位上包括的數(shù)字為 0 到 4;
  2. 每一個(gè)數(shù)位上的數(shù),是它右側(cè)數(shù)位的 5 倍;
  3. 兩個(gè)數(shù)相加時(shí),相同數(shù)位上的數(shù)相加之和如果大于等于 5,就向前進(jìn) 1 位,即:滿五進(jìn)一;

具體來(lái)看就是:

  1. 從右數(shù)第一個(gè)位數(shù)上的數(shù)字代表多少個(gè) 1;
  2. 從右數(shù)第二個(gè)位數(shù)上的數(shù)字代表多少個(gè) 5;
  3. 從右數(shù)第三個(gè)位數(shù)上的數(shù)字代表多少個(gè) 25;
  4. 從右數(shù)第四個(gè)位數(shù)上的數(shù)字代表多少個(gè) 125;

再看一個(gè)圖加深印象:

三、從十進(jìn)制加法到二進(jìn)制加法

1. 十進(jìn)制加法

這個(gè)就不必多說(shuō)了,規(guī)則只有 2 條:

  1. 兩個(gè)數(shù),相同數(shù)位上的數(shù)字進(jìn)行相加;
  2. 每一個(gè)數(shù)位上的相加結(jié)果,滿十進(jìn)一;

例如:


個(gè)位上:4 + 8,結(jié)果是 12,但是十進(jìn)制中沒(méi)有 12 這個(gè)數(shù)字,因此向左側(cè)的高位進(jìn)1,個(gè)位就剩下:12 - 10 = 2。

十位上:7 + 2,再加上進(jìn)位 1,結(jié)果是 10,但是十進(jìn)制中沒(méi)有 10 這個(gè)數(shù)字,因此向左側(cè)的高位進(jìn)1,十位變成:10 - 10 = 0。

百位上:1 加上進(jìn)位 1,結(jié)果是 2。

2. 二進(jìn)制加法

第 0 位:0 + 0 結(jié)果為 0;

第 1 位:1 + 0 結(jié)果為 1;

第 2 位:1 + 1 結(jié)果為 2,但是二進(jìn)制中沒(méi)有 2 這個(gè)數(shù)字,因此需要向左側(cè)的高位進(jìn) 1,于是第 2 位上就剩下 2 - 2 = 0。

第 3 位:1 + 1 等于 2,再加上進(jìn)位 1,結(jié)果就是 3,但是二進(jìn)制中沒(méi)有 3 這個(gè)數(shù)字,因此需要向左側(cè)的高位進(jìn) 1,于是第 3 位上就剩下 3 - 2 = 1。

第 4,5,6,7位計(jì)算均是如此。

3. 十六進(jìn)制加法

第 0 位:E + C,結(jié)果為 26,但是十六進(jìn)制中沒(méi)有 26 這個(gè)數(shù)字,因此需要向左側(cè)的高位進(jìn) 1,于是第 0 位就剩下 26 - 16 = A。

第 1 位:A + 1 等于 B,再加上進(jìn)位 1,結(jié)果就是 C,十六機(jī)制中有這個(gè)數(shù)字。

四、把負(fù)數(shù)計(jì)算轉(zhuǎn)換成正數(shù)計(jì)算

1. 原碼

原碼(true form)是一種計(jì)算機(jī)中對(duì)數(shù)字的二進(jìn)制定點(diǎn)表示方法。原碼表示法在數(shù)值前面增加了一位符號(hào)位(即最高位為符號(hào)位):正數(shù)該位為0,負(fù)數(shù)該位為1(0有兩種表示:+0和-0),其余位表示數(shù)值的大小。

例如,用 8 個(gè) bit (8 位二進(jìn)制數(shù))來(lái)表示一個(gè)數(shù),+11 的原碼為 0000_1011,-11 的原碼就是 1000_1011。

2. 把負(fù)數(shù)計(jì)算變成正數(shù)計(jì)算

我們都知道,CPU 中有加法器,好像從來(lái)沒(méi)有聽說(shuō)過(guò)“減法器”。例如計(jì)算 5 + 8,轉(zhuǎn)換成二進(jìn)制來(lái)計(jì)算:

再來(lái)計(jì)算一下減法:5 - 8,對(duì)于 CPU 來(lái)說(shuō),只會(huì)計(jì)算 5 + 8, 但是不會(huì)計(jì)算 5 - 8。

但是可以轉(zhuǎn)換一下思路,把減法變成加法 5 + (-8),這樣不就可以計(jì)算了嗎?于是計(jì)算機(jī)先驅(qū)者就發(fā)明了反碼:

  1. 正數(shù)的反碼:保持原碼不變;
  2. 負(fù)數(shù)的反碼:原碼中符號(hào)位不變,其余全部取反(-8 的原碼是 1000_1000,反碼就是:1111_0111);

于是 5 + (-8)的計(jì)算過(guò)程就是:

此時(shí),就完美解決了減法問(wèn)題,那么乘法(多加幾次)、除法(多減幾次)問(wèn)題也就跟著解決了。至于如何從數(shù)學(xué)的角度來(lái)證明,那就要問(wèn)那些數(shù)學(xué)家了!

3. 新問(wèn)題:如何表示0?

我們現(xiàn)在可以小結(jié)一下反碼的表示范圍(記住:第一位是符號(hào)位):

  1. 正數(shù)的表示范圍:0000_0000 ~ 0111_1111,也就是十進(jìn)制的 +0 ~ +127 這 128 個(gè)數(shù);
  2. 負(fù)數(shù)的表示范圍:1000_0000 ~ 1111_1111,也就是十進(jìn)制的 -127 ~ -0 這 128 個(gè)數(shù);

有沒(méi)有發(fā)現(xiàn)問(wèn)題:怎么存在 +0 和 -0 這兩個(gè)數(shù)?而且他們的編碼還不一樣:+0 對(duì)應(yīng) 0000_0000,-0 對(duì)應(yīng) 1111_1111。

CPU 雖然就是一個(gè)傻瓜,讓它干啥就干啥,但是 CPU 最不能容忍的就是不確定性!我們都知道 +0 == -0 == 0,它們是同一個(gè)數(shù)字,但是在二進(jìn)制編碼中,居然有兩個(gè)編碼來(lái)表示同一個(gè)數(shù)。

偉大的計(jì)算機(jī)先驅(qū)者又做了這樣一個(gè)決定:正數(shù)保持不變,負(fù)數(shù)整體減 1

也就是說(shuō):符號(hào)位不變,值整體加1,如下:

這樣就成功解決了 -0、+0 的問(wèn)題!

現(xiàn)在 一個(gè) 8 位的二進(jìn)制就可以表示的范圍是:-128 ~ 127,并且中間沒(méi)有任何重復(fù)、遺漏的數(shù)字。

既然每一個(gè)二進(jìn)制表示的值發(fā)生了變化,那么繼續(xù)稱之為反碼不準(zhǔn)確了,此時(shí)給它們一個(gè)新的稱呼:補(bǔ)碼,也就是說(shuō):上圖就變成了這樣:

小結(jié)一下補(bǔ)碼的定義:

  1. 正數(shù)的補(bǔ)碼:保持原碼不變;
  2. 負(fù)數(shù)的補(bǔ)碼:原碼中符號(hào)位不變,其余先全部取反,然后再加1(例如:-8 的原碼是 1000_1000,補(bǔ)碼就是 1111_1000);

此時(shí),我們僅僅是解決了二級(jí)制編碼的表示問(wèn)題,那么:補(bǔ)碼能直接參與運(yùn)算嗎?運(yùn)算結(jié)果會(huì)出現(xiàn)什么問(wèn)題?

4. 補(bǔ)碼的計(jì)算

我們先看一下這個(gè)問(wèn)題:假設(shè)現(xiàn)在時(shí)間是 1 點(diǎn)整,但是你的手表進(jìn)水了,它顯示的是 3 點(diǎn)整,現(xiàn)在你怎么把時(shí)間調(diào)整到 1 點(diǎn)的位置?

  • 方法1:把時(shí)針逆時(shí)針撥動(dòng) 2 個(gè)小時(shí)(3 - 2 = 1);
  • 方法2:把時(shí)針順時(shí)針撥動(dòng) 9 個(gè)小時(shí)到 12 點(diǎn),然后再撥動(dòng) 1 個(gè)小時(shí)(3 + 10 = 1);

對(duì)于時(shí)鐘表盤來(lái)說(shuō),每 12 個(gè)小時(shí)為一圈,可以認(rèn)為:-2 == 10,-1 = 11, -3 = 9,同樣的:-2 == 10, -2 == 22, -2 == 34,...

可以看到規(guī)律是:-2、10、22、34 這些數(shù)字對(duì) 12 取模都得到同一個(gè)數(shù)(取正數(shù)),在數(shù)學(xué)上,兩個(gè)整數(shù)除以“同一個(gè)整數(shù)”,若得相同余數(shù),則這兩個(gè)整數(shù)同余。

表盤中的 12 就是這個(gè)“同一個(gè)整數(shù)”,可以看到這是一個(gè)可“溢出”的系統(tǒng),-2、10、22、34 這幾個(gè)數(shù)在表盤上表示的是一樣的數(shù),所以說(shuō)這幾個(gè)整數(shù)同余。

也就是說(shuō):在計(jì)算的時(shí)候,可以用 10、22、34 這幾個(gè)數(shù)字來(lái)替換 -2,替換之后的計(jì)算結(jié)果是相同的。

那么對(duì)于一個(gè) 8 位 的二進(jìn)制數(shù)來(lái)說(shuō),最多只有 8 位,在計(jì)算過(guò)程中,如果最高位產(chǎn)生了進(jìn)位,就會(huì)被丟棄,所以它也是一個(gè)可“溢出”的系統(tǒng)。那么這里的“同一個(gè)整數(shù)”是多少呢?

從前面的內(nèi)容中可以看到,使用補(bǔ)碼表示的 8 位二進(jìn)制數(shù)表示的范圍是 -128 ~ 127,一共是256 個(gè)數(shù),所以如果對(duì) 256 取模,得到相同的余數(shù),那么這些數(shù)就是同余數(shù)。

例如:-2 和 254 對(duì) 256 取模,得到相同的余數(shù),因此它倆就是同余數(shù),那么在計(jì)算的時(shí)候,就可以用 254 來(lái)代替 -2。

那么我們通過(guò)計(jì)算 3 + (-2) 來(lái)驗(yàn)證一下。

(1) 利用同余數(shù)來(lái)計(jì)算

3 + (-2) == 3 + 254 = 257

257 超過(guò)了最大的表示范圍,所以溢出,結(jié)果就是 257 對(duì) 256 取模,結(jié)果為 1。

(2) 直接用補(bǔ)碼來(lái)計(jì)算

3 的補(bǔ)碼是 0000_0011,-2 的補(bǔ)碼是 1111_1110,在計(jì)算的時(shí)候,把符號(hào)位也參與運(yùn)算:

結(jié)果也是 1,也就是說(shuō):

在二進(jìn)制計(jì)算中,使用補(bǔ)碼來(lái)計(jì)算,“天然”就滿足了“同余定理”。

細(xì)心的讀者可能已經(jīng)發(fā)現(xiàn)了:-2 的二進(jìn)制補(bǔ)碼表示,與 254 的二進(jìn)制自然表示,它們的形式是一樣的!

這種“天然”性,是巧合?還是計(jì)算機(jī)前輩的設(shè)計(jì)結(jié)果?!

五、總結(jié)

這篇文章,我們探討了計(jì)算機(jī)系統(tǒng)的軟件基石:二進(jìn)制系統(tǒng),主要的目的是幫助你理解二進(jìn)制的表示、計(jì)算方式。

 

責(zé)任編輯:姜華 來(lái)源: IOT物聯(lián)網(wǎng)小鎮(zhèn)
相關(guān)推薦

2011-05-25 14:10:38

浮點(diǎn)數(shù)

2023-01-27 20:02:24

數(shù)值字符串二進(jìn)制

2020-06-15 17:05:46

前端二進(jìn)制瀏覽器

2022-10-31 08:02:42

二進(jìn)制計(jì)算乘法

2009-02-27 09:37:33

Google二進(jìn)制代碼

2017-04-11 10:48:53

JS二進(jìn)制

2010-10-13 15:45:23

MySQL二進(jìn)制日志

2018-10-22 14:37:16

二進(jìn)制數(shù)據(jù)存儲(chǔ)

2021-11-10 09:15:00

CPU01 二進(jìn)制Linux

2022-07-18 09:01:15

SwiftApple二進(jìn)制目標(biāo)

2021-01-14 09:40:54

漏洞macOS屬性表文件

2024-10-30 09:50:51

WebGo語(yǔ)言

2010-06-09 13:02:29

MySQL啟用二進(jìn)制日

2009-08-12 18:06:53

C#讀取二進(jìn)制文件

2009-12-16 10:49:42

Ruby操作二進(jìn)制文件

2022-07-26 13:00:01

安全符號(hào)源代碼

2020-10-10 14:27:01

kubernetes 二進(jìn)制部署

2011-12-31 11:22:50

Web新世界

2010-04-16 09:42:25

Fedora 13Nvidia二進(jìn)制驅(qū)動(dòng)

2022-09-05 08:12:28

Google二進(jìn)制Protobuf
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)