程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 原碼、反碼、補碼以及為什麼要用反碼和補碼,原碼補碼要用反碼

原碼、反碼、補碼以及為什麼要用反碼和補碼,原碼補碼要用反碼

編輯:關於C語言

原碼、反碼、補碼以及為什麼要用反碼和補碼,原碼補碼要用反碼


原始博文網址,無意侵權,只是想記下來以後復習的時候方便,

http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

機器數

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

真值

因為第一位為符號位,所以機器數的形式值就不等於真正的數值,例如上面的有符號數1000 0011,其最高位1代表負,其真正數值是-3,而不是形式值131(1000 0011轉換成10進制等於131),所以為了區別起見,將帶符號的機器數對應的真正數值稱為機器數的真值。例如:0000 0001的真值=+000 0001=+1,1000 0001的真值=-000 0001=-1

原碼:

原碼就是符號位加上真值的絕對值,即用第一位表示符號,其余位表示值,比如如果是8位二進制,[+1]原=0000 0001.[-1]原=1000 0001.因為第一位是符號位,所以8位二進制的取值范圍就是:[1111 1111,0111 1111]即[-127,127],原碼是人腦最容易理解和計算的表示方式。

反碼:

反碼的表示方法是:正數的反碼是其本身,負數的反碼是在其原碼的基礎上,符號位不變,其余各個位取反,[+1]=[0000 0001]原= [0000 0001]反,[-1]=[1000 0001]原=[1111 1110]反。可見如果一個反碼表示的是負數,人腦無法直觀的看出來它的數值,通常要將其轉換成原碼再計算。

補碼:

補碼的表示方法是:正整數的二進制補碼與其二進制原碼相同,負整數的二進制補碼,先求與該負數相對應的正整數的二進制代碼,然後所有位取反加1,不夠位數時左邊補1,例如,[+1]=[0000 0001]原=[0000 0001]反=[0000 0001]補,[-1]=[1000 0001]原=[1111 1110]反=[1111 1111]補,對於負數,補碼表示方式也是人腦無法直觀看出其數值的,通常也需要轉換成原碼再計算其數值。

為什麼要使用原碼反碼補碼,

現在我們知道了計算機可以用原碼 反碼 補碼這三種編碼方式表示一個數,對於正數因為三種編碼方式都相同,沒有什麼好解釋的,但是對於負數,負數的原碼反碼補碼是完全不同的,既然原碼才是被人腦直接識別並用於計算方式,那麼為什麼還要用反碼和補碼呢,首先,因為人腦可以知道原碼的第一位是符號位,在計算的時候,我們會根據符號位,選擇對真值區域的加減,但是對於計算機,加減乘除已經是最基礎的運算,要設計的盡量簡單,計算機辨別符號位顯然會讓計算機的基礎電路設計變得十分復雜,於是人們想出了將符號位也參與運算的方法,我們知道,根據運算法則減去一個正數等於加上一個負數,即:1-1=1+(-1)=0;所以機器可以只有加法而沒有減法,這樣計算機運算的設計就更簡單了,那麼如果用原碼計算,1-1=1+(-1)=[0000 0001]原+[1000 0001]原=[1000 0010]原=-2.如果用原碼計算,讓符號位也參與運算,顯然對於減法來說,結果是不正確的,這也就是為什麼計算機內部不用原碼表示一個數,為了解決原碼做減法的問題出現了反碼,如果用反碼計算減法,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].因為機器使用補碼, 所以對於編程中常用到的32位int類型, 可以表示范圍是: [-231, 231-1] 因為第一位表示的是符號位.而使用補碼表示時又可以多保存一個最小值。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved