符號位;原碼,反碼,補碼


1 符號位

        計算機如何存儲數據,因為計算機世界里面所有的數據歸根結底都是由0和1來存儲的,那么如何表達數值的正負呢?只知道書本上說是有一個符號位,當該符號位為0時,表示的是正數,為1時表示負數。我那時沒搞懂為什么這樣規定,我覺得1么,代表正數挺合理的,那么0就自然表示負數咯,所以不解,只能死記硬背:0正1負
  當代絕大多數計算機表示浮點數都是采用IEEE標准的,這里簡化一下,我們只關心符號位,那么對於一個數,計算機其實是以下面的式子來描述它的:(-1)s×X,這里的指數s就是用來決定數值X是正數還是負數,顯而易見,當s=0時,則X為正數(因為任何數的0次冪都是1),當s=1時,則X為負數(因為-1的1次冪為-1),至此我們就理解了為什么符號位為0時表示正數,為1時表示負數啦。

2 機器數

  一個數在計算機中的二進制表示形式,叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號,正數為0,負數為1.比如,十進制中整數+3,若計算機字長為8位,轉換為二進制數為 0000 0000 0000 0000 0000 0000 0000 0011;如果是-3,就是1000 0000 0000 0000 0000 0000 0000 0011。

3 真值

  因為第一位是符號位,所以機器數的形式值就不等於真正的數值。

  例如:有符號數的真值如下

  1000 0000 0000 0000 0000 0000 0000 0011的真值 = -000 0000 0000 0000 0000 0000 0000 0011 = -3;

  0000 0000 0000 0000 0000 0000 0000 0011的真值 = +000 0000 0000 0000 0000 0000 0000 0011 = +3

4 原碼,反碼,補碼的基礎概念和計算方法

  對於一個數,計算機要使用一定的編碼方式進行存儲,原碼,反碼,補碼都是機器存儲一個具體數字的編碼方式。

原碼

  原碼就是用第一位表示符號,其余位表示值,比如如果是32位二進制:

  [+3]原碼 = 0000 0000 0000 0000 0000 0000 0000 0011

   [-3]原碼 = 1000 0000 0000 0000 0000 0000 0000 0011

  因為第一位是符號位,所以32位二進制整數的取值范圍就是:

  [1111 1111 1111 1111 1111 1111 1111 1111 , 0111 1111 1111 1111 1111 1111 1111 1111]  ==> [-2147483647, 2147483647]

反碼

  反碼的表示方法是:

  *正數的反碼是其本身

       *負數的反碼是在其原碼的基礎上,符號位不變,其余各個位取反

     -3 原碼 1000 0000 0000 0000 0000 0000 0000 0011
              反碼 1111 1111 1111 1111 1111 1111 1111 1100

    +3 原碼 0000 0000 0000 0000 0000 0000 0000 0011
       反碼 0000 0000 0000 0000 0000 0000 0000 0011

補碼

  補碼的表示方法是:

  *正數的補碼就是其本身

  *負數的補碼是在其原碼的基礎上,符號位不變,其余各位取反,最后+1(即在反碼的基礎上+1)

     -3 原碼 1000 0000 0000 0000 0000 0000 0000 0011
              反碼 1111 1111 1111 1111 1111 1111 1111 1100
              補碼 1111 1111 1111 1111 1111 1111 1111 1101

      +3 原碼 0000 0000 0000 0000 0000 0000 0000 0011
         反碼 0000 0000 0000 0000 0000 0000 0000 0011
              補碼 0000 0000 0000 0000 0000 0000 0000 0011

 

5. 為何要使用原碼, 反碼和補碼

計算機可以有三種編碼方式表示一個數. 對於正數因為三種編碼方式的結果都相同:

以下以8位機器為例

[+1] = [00000001] = [00000001] = [00000001]

所以不需要過多解釋. 但是對於負數:

[-1] = [10000001] = [11111110] = [11111111]

可見原碼, 反碼和補碼是完全不同的. 為何還會有反碼和補碼呢?

首先, 因為人腦可以知道第一位是符號位, 在計算的時候我們會根據符號位, 選擇對真值區域的加減. (真值的概念在本文最開頭).

但是對於計算機, 加減乘數已經是最基礎的運算, 要設計的盡量簡單. 計算機辨別"符號位"顯然會讓計算機的基礎電路設計變得十分復雜! 於是人們想出了將符號位也參與運算的方法.

根據運算法則減去一個正數等於加上一個負數, 即: 1-1 = 1 + (-1) = 0 , 所以機器可以只有加法而沒有減法, 這樣計算機運算的設計就更簡單了.

於是人們開始探索 將符號位參與運算, 並且只保留加法的方法. 首先來看原碼:

計算十進制的表達式: 1-1=0

為了解決原碼做減法的問題, 出現了反碼:

1 - 1 = 1 + (-1) = [0000 0001] + [1000 0001]= [0000 0001] + [1111 1110] = [1111 1111] = [1000 0000] = -0

發現用反碼計算減法, 結果的真值部分是正確的. 而唯一的問題其實就出現在"0"這個特殊的數值上. 雖然人們理解上+0和-0是一樣的, 但是0帶符號是沒有任何意義的. 而且會有[0000 0000]和[1000 0000]兩個編碼表示0.

於是補碼的出現, 解決了0的符號以及兩個編碼的問題:

1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [0000 0001] + [1111 1111] = [0000 0000]=[0000 0000]

這樣0用[0000 0000]表示, 而以前出現問題的-0則不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001] + [1111 1111] = [1111 1111] + [1000 0001] = [1000 0000]

-1-127的結果應該是-128, 在用補碼運算的結果中, [1000 0000] 就是-128. 但是注意因為實際上是使用以前的-0的補碼來表示-128, 所以-128並沒有原碼和反碼表示.(對-128的補碼表示[1000 0000]補算出來的原碼是[0000 0000], 這是不正確的)

使用補碼, 不僅僅修復了0的符號以及存在兩個編碼的問題, 而且還能夠多表示一個最低數. 這就是為什么8位二進制, 使用原碼或反碼表示的范圍為[-127, +127], 而使用補碼表示的范圍為[-128, 127].

 

部分內容轉載自別處。    

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM