計算機基礎之原碼補碼那些事

寫這篇文章的目的是把零零碎碎的那些知識點都作個記錄,到時候好回過頭複習。html

1.(1)補碼概念:摘自百度https://baike.baidu.com/item/%E8%A1%A5%E7%A0%81/6854613?fr=aladdin編程

在計算機系統中,數值一概用補碼來表示和存儲。緣由在於,使用補碼,能夠將符號位和數值域統一處理;同時,加法和減法也能夠統一處理。此外,補碼與原碼相互轉換,其運算過程是相同的,不須要額外的硬件電路。函數

(2)模的概念ui

「模」是指一個計量系統的計數範圍。如時鐘等。計算機也能夠當作一個計量機器,它也有一個計量範圍,即都存在一個「模」。編碼

例如:在以12模的系統中,加8和減4效果是同樣的,所以凡是減4運算,均可以用加8來代替。對「模」而言,8和4互爲補數。實際上以12模的系統中,11和1,10和2,9和3,7和5,6和6都有這個特性。共同的特色是二者相加等於模。spa

https://blog.csdn.net/u013814701/article/details/63255237.net

https://zhidao.baidu.com/question/1239927115133880859.html設計

2.補碼的計算:(之十進制轉二級制)htm

(1)正整數轉成二進制。要點必定必定要記住哈:除二取餘,而後倒序排列,高位補零。口訣:除二取餘,而後倒序排列,高位補零。blog

(2)負整數轉換成二進制: 方法:先是將對應的正整數轉換成二進制後,對二進制取反,而後對結果再加一。

(3)小數轉換爲二進制的方法:略

摘自:https://jingyan.baidu.com/article/597a0643614568312b5243c0.html

 

 

tip:1.原碼中0有2種表示方法(正零和負零),補碼中0只有一種表示方法(正零和負零的表示方法一致)

爲何補碼中0只有一種表示?

百度答案:樓上的說法不正確的~補碼的存在是爲了變減法爲加法,簡化了計算過程,即硬件的設計難度.首先要知道兩個零是怎麼來的,0包括+0和-0,在原碼和反碼中根據其計算公式,有兩種形式,而對於補碼來講+0,真值爲0,000000和-0,其真值爲1,0000000補碼:一個數若是爲正,則它的原碼、反碼、補碼相同;一個數若是爲負,則符號位爲1,其他各位是對原碼取反,而後整個數加1.爲了簡單起見,咱們用1個字節來表示一個整數:問題:0的補碼錶示:
+0的補碼:00000000
-0的補碼:第一步:11111111 第二步+1= 1 00000000 第三部:進位1被丟棄 您明白了嗎?

補數相加後不能大於模

摘自:https://www.zybang.com/question/2ded8d9f283e84dd515c8ce36da28b32.html

 2.補碼加法中天然丟棄和溢出的區別

十進制數相加:(-15) + (-20) = (-35)
用補碼計算,就會有天然丟棄的現象。

(-15) 補= 1111 0001
(-20) 補= 1110 1100
相加:--------
可得: (1)1101 1101

括號中的1,是進位,天然丟棄。

剩下的 1101 1101,就是(-35)補。

===================================

八位的補碼,能夠表示十進制數-128~+127。
運算結果超出這個範圍,就溢出了。

十進制數計算:(+80) + (+90) = (+170)
用補碼計算,就會有溢出。

(+80) 補= 0101 0000
(+90) 補= 0101 1010
相加:--------
可得: (0) 1010 1010

進位是0。
剩下的 1010 1010,倒是(-86)補。

爲何不是 (+170)補?
就是由於,超出範圍,溢出了。

3.補碼(爲何按位取反再加一):告訴你一個其實很簡單的問題

   首先,閱讀這篇文章的你,確定是一個在網上已經糾結了好久的讀者,由於你查閱了全部你能查到的資料,而後他們都會很耐心的告訴你,補碼:就是按位取反,而後加一。準確無誤,毫無破綻。可是,你搜遍了全部俯拾便是並且準確無誤的答案,卻仍然選擇來看這篇絕不起眼的文章,緣由只有一個,只由於你尚未獲得你想要的東西。

             由於你想要的,不是1+1=2,而是,1+1爲何等於2。固然,咱們不討論1+1的問題。咱們討論的,是補碼。

             你已經困惑了好久,你明明知道補碼就是按位取反,而後加一,可是你想知道的,不是它怎麼求滴,而是,它怎來滴。固然,對於閱讀這篇文章的你,既然想要知道這個答案,必定是有必定編程基礎的讀者,確定知道補碼與有符號數與無符號數的關係(有符號數指帶有正負號的數,無符號能夠理解爲只大於0的數),你所查閱的全部資料首先都會用一個8位的二進制數給你舉例,ok,咱們也用一個8位的二進制數。

             8位二進制數,最小00000000,最大數11111111,換算十進制爲0~255,固然,全部的參考資料都會這樣講,並且這也不是你想要的,但咱們必須說下去。1~255,一共255的字符,再加上最前面的0,一共256個字符。如今,咱們要用一個8位二進制數字來表示一個負數,但是二進制裏沒有負號,誰都知道二進制裏只有0,1,再無其餘符號。那麼因此咱們必須用一種方式來代替正負,也就是咱們規定,固然是人規定的,而不是電腦,咱們規定這個8位的二進制數的最前面一位數來表示這個數的正負,0表明是正,1表明是負。那麼當第一位是0時,咱們一共能夠表示00000000~01111111這麼多正數,由於第一位必須是0來表明正數;當第一位是1時,咱們一共能夠表示10000000~11111111這麼多負數,而後,咱們用00000000~01111111來表明0~127,那豈不是10000000~11111111表明  -0  ~  -127??但是網上都說不能有 負0,但是我覺的沒什麼不妥啊,負0不仍是0 嗎?10-0=10,不就是至關於10+(-0)=10嗎,如今咱們不討論正負0的問題,咱們來討論一個小學生的問題。

             咱們如今要把00000000~11111111分紅兩組數,一組是正數,另外一組是負數,正數是0,1,2,3,4,5,6,7,8,… 負數是 -1,-2,-3,-4,-5,-6,-7,-8,… 那麼這裏就有一個小學問題,那就是1+(-1)確定要等於0,2+(-2)=0,他們是相反數,相加等於0,小學生都會。後面都是同樣,那麼如今咱們使用上面的編碼的方式進行一個計算,如今上面的編碼中 1 對應的二進制是00000001,-1對應的二進制是10000001,而後你把這倆二進制數加起來,看看等於幾,對,答案是10000010,不是00000000,也不是10000000,  10000010在上面的編碼中表明 -2,00000000和10000000都在上面表明0,但是結果並非他們。而00000001與10000001分別對應着1和-1,加起來理論的結果應該是0纔對,也就是說上面的編碼是錯誤的。

            或許接下來不少資料又討論了反碼,可是咱們不,咱們來求一個一元一次函數,一個小學的函數,1+x=0,求x=?,答:-1。沒錯,並且準確無誤。那麼如今問題來了,前面的正數編碼應該是沒有錯的,00000000表明0,  00000001表明1,這些都符合咱們的習慣,那麼出錯的是在後面的負數編碼上,咱們到底該如何編碼對應負數編碼它才能正確呢,由於咱們知道1+(-1)必須等於0,也就是他們對應的二進制相加也必須等於0,1對應00000001,那麼00000001+x=00000000,裏面的x就應該代替 -1的二進制編碼纔對,這樣,咱們獲得 x=11111111,你們看一下這和按位取反,而後加一的結果同樣嗎。

           因此咱們的結論是,一個正數對應的負數(也就是倆相反數),這兩個數的二進制編碼加起來必須等於0纔對,因此咱們只要知道其中一個數的編碼x,而後用0-x就是他對應的數的編碼,這樣的話,從0~127,咱們用(0 - 其中一個二進制數的編碼)=(另外一個二進制數的編碼),例如 2 的二進制編碼是00000010,那麼-2 的二進制編碼就是0 - 00000010=11111110,由於他就應該這樣,由於它就是一個小學問題,他倆加起來就應該等於0。那麼1000000對應的編碼是多少呢,固然也必須知足加起來等於0才行,那麼10000000+x=0,求解x,答x=10000000,仍是它自己,也就是在00000000~11111111這個範圍裏全部的二進制數都沒法知足它,也就是沒有一個數加上它等於0,可是兩個數要有對應的編碼,就必須加起來等於0才行,其實不止它沒有,0也沒有,0+x=0,那麼x=0,也是它自己,既然這樣了,那麼也沒有辦法了,迫不得已只能作單身漢了,而後咱們規定,既然10000000第一位是1,表明負數,那麼咱們規定它是一個負數,那麼10000000就代替了-128,並且,它只本身一我的,也就是隻有-128,沒有正數128。

         而後,他們每一個數都有了本身對應的編碼,並且準確無誤。1~127對應-1~ -127,再加上兩個單身漢0和-128。而後呢,不知道誰起的名字,就把這種編碼叫作了補碼,若是你樂意,你也能夠給它起個名字。可是呢,還有一個問題,爲何補碼的求法是按位取反再加一呢,其實當你不明白爲何各大書籍都要用按位取反來計算補碼的時候,咱們徹底能夠直接用0減去它就獲得他相反數的二進制編碼了,譬如隨便一個十六進制數 6C ,那麼咱們能夠直接0-6C就獲得他的相反數的補碼了,結果爲十六進制的94,跟按位取反再加一的效果同樣。

         如今咱們知道補碼是怎麼來的了,也就是爲了保證兩個相反數對應二進制的和必須是0,而後又不知道誰給它起了補碼這個名字。補碼補碼,有沒有感受兩個相反數是互補的呢,也就是任意兩個相反數加起來必定等0,其中一個數變大,另外一個就必定會變小互補保證結果爲0。可是你確定還在糾結,爲啥要按位取反,爲啥還要加一呢。其實,這涉及到一個二進制減法的問題,你既然知道補碼這個概念,就必定會知道有進位丟失這麼個東西。如今咱們知道了補碼是怎麼來的,也就是(00000000 - 其中一個正數的補碼)=(這個數相反數的補碼),那麼咱們知道了1的二進制是00000001,那麼咱們來求-1的補碼,也就是應該00000000 - 00000001=?,咱們該怎麼計算這個二進制減法呢,並且仍是一個小數減去大數,連借位都沒地方借,前面咱們提到進位丟失這個東西,那麼咱們來計算一個算式,11111111+00000001=?知道進位丟失的你,確定知道加起來後等於00000000,雖然結果應該是100000000(後面是8個0),可是隻能有8位,因此最高位的1丟失了,那麼如今好了,也就是說,咱們能夠把00000000看作(11111111+00000001)由於他倆是相等的,咱們已經計算過的了,那麼咱們如今就能夠把前面講的公式中的00000000換成(11111111+00000001),也就是咱們要計算-1的補碼,咱們就0-1的編碼,也就是00000000-00000001,也就是(11111111+00000001)-00000001=(-1的補碼),這個算式我覺的你應該會計算了,大數減少數,到如今,或許你如今已經發現什麼了,是的,你發現了以前一直迷惑你的一個東西,「按位取反再加一」,可是可能還有一點迷惑,咱們繼續,由於咱們每次都是用一個0減去一個數的補碼來獲得另外一個數的補碼,也就是裏面的(11111111+00000001)是不變的,由於它就是0,那麼咱們如今要求一個數的補碼,就是(11111111+00000001)- 一個數的補碼=它相反數的補碼,我們把括號去掉,也就是11111111 - 一個數的補碼+00000001=它相反數的補碼,這是加法交換法則,只是把位置交換一下,小學生都會的,而後呢再加個括號方便咱們理解,也就是(1111111 - 一個數的補碼)+00000001=它相反數的補碼。好了,問題來了,(11111111 - 一個數的補碼)的結果是什麼,這個你內心應該是清楚的,你也能夠算一下,它正好的等於它的反碼,也就是按位取反的一個數,其實也好理解,你減幾個數就看見規律了,描述好麻煩,如今好了,也就是(11111111 - 一個數的補碼)=這個數的反碼,也就是(11111111 - 一個數的補碼)=把這個數按位取反,到如今,你應該你已經很清楚他是怎麼來的了。

         那麼咱們如今就能夠把公式寫成這樣,(11111111 - 一個數的補碼)+00000001=它相反數的補碼,如今咱們知道了(11111111 - 一個數的補碼)=把這個數按位取反,而後把公式裏的(11111111 - 一個數的補碼)換成 「按位取反」,也就是 (按位取反)+000000001=它相反數的補碼,如今,按位取反,再加一,就終於出來了,這就是各大書籍資料所講的,補碼=按位取反+1..。好了,真相大白

         本文章屬我的領悟,錯誤必有,不吝賜教

 

                                                                                                                                                                                         2014-聖誕節平安夜-12.24

相關文章
相關標籤/搜索