2020-10-27(原码,反码,补码的产生)
文章目錄
- 1. 補碼誕生的背景
- 2. 原碼、反碼、補碼
- 2.1 原碼
- 2.2 反碼
- 2.3 補碼
- 3. 加減法
- 3.1 普通算術(shù)加減法
- 3.2 模N加減法
1. 補碼誕生的背景
不論是在生活中還是虛擬網(wǎng)絡(luò)中,人們總是習(xí)慣與10進制數(shù)字打交道,很容易理解10進制的加減乘除運算,但是我們知道計算機無法直接理解10進制,只能識別高低電平,一般人為設(shè)定0為低電平,1為高電平,所以又稱計算機是二進制的。在計算機發(fā)展早期,人們要想使用計算機,只能使用計算機看懂的二進制與計算機打交道,如穿孔紙帶,人們使用穿孔紙帶將程序和數(shù)據(jù)轉(zhuǎn)換為二進制碼,帶孔為1,無孔為0,計算機讀取并處理完成后,同樣在紙帶上以二進制打孔輸出計算結(jié)果,一般人很難操作這種早期計算機,只能是專業(yè)人士才能處理二進制的轉(zhuǎn)換。隨著科技的進步,普通人也能熟練的操作計算機,表面上似乎計算機已經(jīng)理解了10進制,但是實際上,計算機最底層還是二進制的,這就需要10進制到二進制的自動轉(zhuǎn)換以及使用二進制進行各種運算。 10進制到二進制的轉(zhuǎn)換需要考慮兩方面,第一個是編碼格式,二進制中只有0和1,不同于常用的10進制使用 + 或者 - 符號代表正負數(shù),要想讓二進制只使用1和0代表正負數(shù),需要找到合適的編碼格式;第二個是運算,以加減運算為例,計算機內(nèi)部是比較復(fù)雜的,計算機實現(xiàn)加法運算是很容易的,若直接作減法則比較復(fù)雜,需要處理借位等等,內(nèi)部邏輯組件會增多,所以計算機一般在減去一個數(shù)的時候會轉(zhuǎn)成加上這個被減數(shù)的負數(shù),將減法轉(zhuǎn)換成了加法,即A - B = A + (-B)。所以需要找到一種滿足這兩個方面的編碼,目前10進制轉(zhuǎn)換成二進制主要有三種方式:原碼、反碼、補碼,下面將從編碼格式和運算兩方面對比這三種編碼格式。
2. 原碼、反碼、補碼
2.1 原碼
原碼是最簡單也是最直觀的從10進制到二進制的編碼格式,人為規(guī)定原碼的最高位為符號位,正數(shù)為0,負數(shù)為1,其余所有位為10進制數(shù)的絕對值。如下面例子:
原碼的優(yōu)點是編碼格式對人很友好,類似十進制中的正負號,原碼用最高位0和1分別代碼正負數(shù),很直觀的表示了正負數(shù)。但是原碼也有一個很大的缺點,就是無法將減法轉(zhuǎn)換成加法運算,如:4 - 2 (10進制)= 4 + (-2)= 0 100 + 1 010 (二進制原碼) = 1110 (二進制原碼)= -6 (10進制) 上面例子計算4-2,將4-2轉(zhuǎn)換成4+(-2)并用原碼計算,得出的結(jié)果錯誤,原碼雖然很直觀轉(zhuǎn)換了10進制數(shù),但是計算輸出的原碼值并不正確,所以計算機不能直接使用原碼存儲和計算。
2.2 反碼
反碼的出現(xiàn),主要是為了解決原碼無法執(zhí)行減法運算的問題,人為規(guī)定反碼最高位為符號位,正數(shù)為0,負數(shù)為1,反碼正數(shù)與原碼正數(shù)格式一致,反碼負數(shù)為負數(shù)絕對值的原碼按位分別取反,如下面例子:
反碼的負數(shù)編碼格式不像原碼那樣直觀,但是卻可以將減法轉(zhuǎn)換成加法了,反碼減法規(guī)則為:A - B = A + (-B),如果最高位發(fā)生了溢位,則需要在最低位加上1,如下面兩個例子:1)4 - 2 (10進制)= 4 + (-2)= 0 100 + 1 101 (二進制反碼) = 1 0001 (二進制反碼,發(fā)生了溢位)= 0001 + 0001(最低位加1) = 0010 (二進制反碼)= 2(10進制)2)2 - 2 (10進制)= 2 + (-2)= 0 010 + 1 101 (二進制反碼) = 1111 (二進制反碼)= - 0 (10進制) 運用反碼減法規(guī)則,得到的上面兩個例子的減法結(jié)果是正確的,所以計算機是可以使用反碼存儲和計算的,早期的計算機如CDC 6000、LINC、PDP-1等都是使用反碼的,但是反碼也有兩個缺點:1)0有兩種編碼,+0 (0000)和 -0 (1111),在判斷0時,需要分別判斷0000和1111;2)反碼減法的算法規(guī)則比較復(fù)雜,需要增加計算機內(nèi)部邏輯組件額外判斷溢位,會影響計算效率。
2.3 補碼
補碼是現(xiàn)代計算機使用的編碼格式,解決了上面反碼的兩個缺點。正數(shù)的補碼與原碼格式相同,負數(shù)的補碼是將負數(shù)絕對值的原碼分別按位取反,并加1,如下面例子
補碼的減法規(guī)則比較簡單,按照最簡單的轉(zhuǎn)換公式A-B = A + (-B),當(dāng)減去一個數(shù)時直接轉(zhuǎn)換成加上被減數(shù)的負數(shù)即可,不用像反碼那樣額外處理溢位,如下面兩個例子:1)4 - 2 (10進制)= 4 + (-2)= 0 100 + 1 110 (二進制補碼) = 1 0010 (二進制補碼,發(fā)生了溢位,直接丟棄溢位)= 0010(二進制補碼) = 2(10進制)2)2 - 2 (10進制)= 2 + (-2)= 0 010 + 1 110 (二進制補碼) = 1 0000(二進制補碼,發(fā)生了溢位,直接丟棄溢位)= 0000 (二進制補碼) = 0(10進制) 使用了補碼的加法,上面兩個例子得出的結(jié)果都是正確的,相對于反碼,補碼加法更簡單,直接丟棄溢位,不需要針對溢位單獨處理,所以用補碼做運算效率高。雖然補碼運算過程很簡單,但是轉(zhuǎn)換和運算規(guī)則卻很難理解,要弄明白其中的原理,就需要揭開補碼背后的數(shù)學(xué)奧秘。
3. 加減法
加減運算有兩種運算方式,一種是普通算術(shù)加減法,通常生活中使用的是10進制普通算術(shù)加減法;另一種是模N加減法,計算機補碼執(zhí)行加減運算,則是使用了模N加減法。
3.1 普通算術(shù)加減法
普通算術(shù)加減法是我們在生活中一直使用的,也是最簡單和最容易理解的,通常人為使用 + 和 - 符號規(guī)定正負數(shù),正數(shù)通常省略 + 符號, 如果10,20,-10,-20,正負數(shù)的加減運算則可以看成是一維運算,如下圖:
上圖是普通算術(shù)加減法示意圖,當(dāng)執(zhí)行加法運算時,需要向右移動,比如0+3,在0位置向右移動3位,即為0+3的結(jié)果;同樣的,當(dāng)執(zhí)行減法運算,向左移動。向左和向右是沒有盡頭的,可以一直移動到正的無窮大或者負的無窮大。普通算術(shù)加減法簡單直觀,很容易被人理解,但是對于計算機要實現(xiàn)這樣的算術(shù)加減法,既要區(qū)分正負數(shù),又要分別實現(xiàn)加減法,設(shè)計就會很復(fù)雜,效率會很低,所以這套算術(shù)加減法并不適用計算機。所以需要找到一種不需要區(qū)分正負數(shù)就可以實現(xiàn)加減法轉(zhuǎn)換的規(guī)則,那么計算機運行效率就會最高。
3.2 模N加減法
模N加減法正是不需要區(qū)分正負數(shù)就可以實現(xiàn)加減法轉(zhuǎn)換的運算方式,不同于普通算術(shù)加減法,它是二維運算,要理解模N加減法比較困難,可以先用生活最典型的時鐘舉例,如下圖:
上面是生活中常見的時鐘,如果當(dāng)前時間為凌晨1點,要知道5個小時之后的時間是多少,只需要順時針旋轉(zhuǎn)5格,指向了6點,即為1+5的結(jié)果;如果想知道5個小時之前的時間是多少,需要逆時針旋轉(zhuǎn)5格,指向晚上8點,即為1-5的結(jié)果。時鐘順時針相當(dāng)于時間向前走,逆時針相當(dāng)于時間往后走,但是時鐘不會指向無窮大的數(shù),當(dāng)轉(zhuǎn)過24個小時(24小時制)又回到了原點。在時鐘轉(zhuǎn)動中,1-5的最終結(jié)果為晚上8點,逆時針旋轉(zhuǎn)5個小時就可以得到正確結(jié)果,同時也可以順時鐘旋轉(zhuǎn)19個小時(24-5,24小時制),兩種方式旋轉(zhuǎn)都最終指向了晚上8點。所以任意逆時針旋轉(zhuǎn)得到的結(jié)果都能通過順時鐘旋轉(zhuǎn)得到,當(dāng)逆時針旋轉(zhuǎn)N個小時,與順時針旋轉(zhuǎn)24-N小時相等,24又稱為模,如果把順時針看成是加法,逆時針看成是減法,那么時鐘旋轉(zhuǎn)可以看成模24的加減法運算,滿足公式A-m=A+(24-m),即在時鐘任一時刻A點,從A點逆時針旋轉(zhuǎn)m個小時得到的結(jié)果,與從A點順時針旋轉(zhuǎn)24-m得到的結(jié)果一致。模N運算將減法轉(zhuǎn)換成了加法。 計算機使用的二進制位數(shù)是有限制的,比如4位,8位,16位,64位等等,當(dāng)數(shù)值太大超過最大位數(shù)時,會發(fā)生溢出,重新歸0,所以計算機的二進制能表示的數(shù)不是無窮大的,由于溢出歸零的特點,更像時鐘旋轉(zhuǎn),如下圖:
上圖的四位二進制表示了從0000-1111,當(dāng)超出1111時,四位已無法表示,會發(fā)生溢出,高于四位的位會被丟掉,比如1111加上2等于10001,10001包含五位二進制,最高位1會被丟掉,實際結(jié)果為0001,與時鐘運算很相似,相當(dāng)于在1111順時針旋轉(zhuǎn)了2個數(shù)。在時鐘運算中,將順時針看成加法,逆時針看成減法,那么時鐘運算可以看成是模24的加減法,同理四位二進制也可以看成是模N的加減法,在4位二進制中,轉(zhuǎn)一圈為2^4=16,所以4位二進制的加減法為模16的加減法,減法很容易的就被轉(zhuǎn)換成了加法,即滿足模N加減法公式:A-m=A+(16-m)。 雖然根據(jù)模N加減法實現(xiàn)了加減法轉(zhuǎn)換,但此時又有新的問題,4位二進制只有1和0,是沒有區(qū)分正負數(shù)的,而人們在計算的時候是要區(qū)分正負數(shù)的,所以需要人為將部分二進制劃分為負數(shù),另一部分劃分為正數(shù),根據(jù)模N加減法公式A-m=A+(16-m),當(dāng)A為零點時,根據(jù)模N加減法公式得到 0-m=0+16-m,即-m=16-m,即將零點A逆時針移動m得到負數(shù)m,同時這個負數(shù)m也可以從零點A順時針移動16-m得到,零點A可以為上面四位二進制任意一位,比如定義0000或者0001為零點都是可以的,但是為了簡單運算,人為規(guī)定0000為零點,0000逆時針方向的為負數(shù),順時針方向的為正數(shù)。如在0000逆時針旋轉(zhuǎn)1個數(shù)或者順時針旋轉(zhuǎn)16-1得到1111,那么1111代表-1,相應(yīng)的順時針移動一個數(shù)為+1,即用0001表示+1;同理在0000逆時針旋轉(zhuǎn)2個數(shù)或者順時針旋轉(zhuǎn)16-2得到1110,那么1110代表-2,相應(yīng)的順時針移動兩個數(shù)為+2,即用0010表示+2;同理1101和0011分別為-3和+3,1100和0100分別為-4和+4,1011和0101分別為-5和+5,1010和0110分別為-6和+6,1001和0111分別為-7和+7,但是1000比較特殊,0000逆時針旋轉(zhuǎn)8個數(shù)得到1000,所以1000為-8,相應(yīng)的順時針旋轉(zhuǎn)8個數(shù)也得到了1000,1000既能表示-8又能表示+8,為了不產(chǎn)生沖突,人為規(guī)定1000為-8。如下圖:
上圖中的四位二進制根據(jù)模N加減法劃分出了正負數(shù),同理對任意n位二進制,模N等于=2^n,根據(jù)上面的模N加減法公式得到-m = N - m = 2^n - m = (2^n -1) - m + 1,最終得到了負數(shù)推導(dǎo)公式-m = (2^n -1) - m + 1,(2^n-1)-m即為負數(shù)的原碼絕對值按位取反,之后再加上1可以快速得到負數(shù)編碼,又稱這種負數(shù)編碼為補碼。補碼負數(shù)范圍轉(zhuǎn)換成10進制為 -1 ~ -2^(n-1),正數(shù)范圍轉(zhuǎn)換成10進制為 0 ~ 2^(n-1)-1,所以補碼轉(zhuǎn)換成10進制為 -2^(n-1) ~ 2^(n-1)-1。4. 總結(jié) 要想弄清楚補碼,必須要弄清楚補碼要解決的問題,計算機是二進制的,無法直接表示正負數(shù),另外在計算機內(nèi)部直接實現(xiàn)減法,也會影響計算機效率,所以人們希望要找到一種既能使用二進制表示10進制正負數(shù)的編碼格式,同時這種編碼格式又能滿足將減法轉(zhuǎn)換成加法進行運算,同時滿足這兩個條件有反碼和補碼,但由于反碼中的0有兩個編碼格式,另外反碼加法運算也比較復(fù)雜,慢慢地反碼被淘汰了。補碼剛好解決了反碼的兩個缺點,所以補碼成了現(xiàn)代計算機的通用編碼。 補碼加減法運算不同于常規(guī)的算術(shù)加減法,補碼使用了模N加減法,要想完全理解補碼,首先要理解模N加減法。
總結(jié)
以上是生活随笔為你收集整理的2020-10-27(原码,反码,补码的产生)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020-10-27(补码1000000
- 下一篇: 2020-10-29(Android