乙個數在計算機中的二進位制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用乙個數的最高位存放符號, 正數為0, 負數為1.
比如,十進位制中的數 +3 ,計算機字長為8位,轉換成二進位制就是00000011。如果是 -3 ,就是 10000011 。那麼,這裡的 00000011 和 10000011 就是機器數。
因為第一位是符號位,所以機器數的形式值就不等於真正的數值。例如上面的有符號數 10000011,其最高位1代表負,其真正數值是 -3 而不是形式值131(10000011轉換成十進位制等於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] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可見如果乙個反碼表示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算。
補碼的表示方法是:正數的補碼就是其本身;的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]補
[-1] = [10000001]原 = [11111110]反 = [11111111]補
對於負數, 補碼表示方式也是人腦無法直**出其數值的. 通常也需要轉換成原碼在計算其數值.
模模的概念可以幫助理解補數和補碼。
「模」是指乙個計量系統的計數範圍。如時鐘等。計算機也可以看成乙個計量機器,它也有乙個計量範圍,即都存在乙個「模」。例如:
時鐘的計量範圍是0~11,模=12。表示n位的計算機計量範圍是0~2^(n)-1,模=2^(n)。
「模」實質上是計量器產生「溢位」的量,它的值在計量器上表示不出來,計量器上只能表示出模的餘數。任何有模的計量器,均可化
減法為加法運算。
例如:假設當前時針指向10點,而準確時間是6點,調整時間可有以下兩種撥法:一種是倒撥4小時,即:10-4=6;另一種是順撥8小時:10+8=12+6=6
在以12模的系統中,加8和減4效果是一樣的,因此凡是減4運算,都可以用加8來代替。對「模」而言,8和4互為補數。實際上以12模的系統中,11和1,10和2,9和3,7和5,6和6都有這個特性。共同的特點是兩者相加等於模。
對於計算機,其概念和方法完全一樣。n位計算機,設n=8, 所能表示的最大數是11111111,若再加1成為100000000(9位),但因只有8位,最高位1自然丟失。又回了00000000,所以8位
二進位制系統的模為2^8。在這樣的系統中
減法問題也可以化成加法問題,只需把
減數用相應的
補數表示就可以了。把補數用到計算機對數的處理上,就是補碼。
在開始深入學習前, 我的學習建議是先」死記硬背」上面的原碼, 反碼和補碼的表示方式以及計算方法.
現在我們知道了計算機可以有三種編碼方式表示乙個數. 對於正數因為三種編碼方式的結果都相同:
[+1] = [00000001]原 = [00000001]反 = [00000001]補
所以不需要過多解釋. 但是對於負數:
[-1] = [10000001]原 = [11111110]反 = [11111111]補
可見原碼, 反碼和補碼是完全不同的. 既然原碼才是被人腦直接識別並用於計算表示方式, 為何還會有反碼和補碼呢?
首先, 因為人腦可以知道第一位是符號位, 在計算的時候我們會根據符號位, 選擇對真值區域的加減. (真值的概念在本文最開頭). 但是對於計算機, 加減乘數已經是最基礎的運算, 要設計的盡量簡單. 計算機辨別」符號位」顯然會讓計算機的基礎電路設計變得十分複雜! 於是人們想出了將符號位也參與運算的方法. 我們知道, 根據運算法則減去乙個正數等於加上乙個負數, 即: 1-1 = 1 + (-1) = 0 , 所以機器可以只有加法而沒有減法, 這樣計算機運算的設計就更簡單了.
於是人們開始探索 將符號位參與運算, 並且只保留加法的方法. 首先來看原碼。計算十進位制的表示式: 1-1=0
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
如果用原碼表示, 讓符號位也參與計算, 顯然對於減法來說, 結果是不正確的.這也就是為何計算機內部不使用原碼表示乙個數.
為了解決原碼做減法的問題, 出現了反碼。計算十進位制的表示式:
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]補算出來的原碼是[1000 0000]原, 這是不正確的)
使用補碼, 不僅僅修復了0的符號以及存在兩個編碼的問題, 而且還能夠多表示乙個最低數. 這就是為什麼8位二進位制, 使用原碼或反碼表示的範圍為[-127, +127], 而使用補碼表示的範圍為[-128, 127].
因為機器使用補碼, 所以對於程式設計中常用到的32位int型別, 可以表示範圍是: [-2^31, 2^31-1] 因為第一位表示的是符號位.而使用補碼表示時又可以多儲存乙個最小值.
以下是本人的補充的理解,不知道是否正確:
由於計算機中的數字用補碼表示,例如8bit的byte型別的表示範圍為:
[-128, 127]
0 = [0000 0000](補)
-128 = [1000 0000](補)
127 = [0111 1111](補)
當byte型別的變數超上限127時,如:
+128 = -(-128)= 127 + 1
= [0111 1111](補)+ [0000 0001](補)
= [1000 0000](補)
= -128
+129 = 127 + 2
= [0111 1111](補)+ [0000 0010](補)
= [1000 0001](補)
= [1111 1111](原)
= -127
當byte型別的變數超過下限-128時:
-129 = -128 - 1
= [1000 0000](補) +[1111 11111](補)
= [0111 1111](補)
= 127
-130 = -128 - 2
= [1000 0000](補)+ [1111 1110](補)
= [0111 1110](補)
= 126
計算機原碼 反碼 補碼詳解
機器數乙個數在計算機中的二進位制表示形式,叫做這個數的機器數。機器數是帶符號的,在計算機用乙個數的最高位存放符號,正數為0,負數為1.比如,十進位制中的數 3 計算機字長為8位,轉換成二進位制就是00000011。如果是 3 就是 10000011 那麼,這裡的 00000011 和 1000001...
計算機 原碼 反碼 補碼
在計算機中,用補碼來表示數字,因為 1 這樣可以比較方便的表示0 保證0作為正數或者負數補碼都是00000000 2 計算時用補碼直接加減就是最終數值 符號位參與運算 1.原碼 原碼就是符號位加上真值的絕對值,即用第一位表示符號,其餘位表示值.比如如果是8位二進位制 1 原 0000 0001 1 ...
計算機原碼, 反碼, 補碼
乙個數在計算機中的二進位制表示形式,叫做這個數的機器數。機器數是帶符號的,在計算機用乙個數的最高位存放符號,正數為0,負數為1.因為第一位是符號位,所以機器數的形式值就不等於真正的數值。例如上面的有符號數 10000011,其最高位1代表負,其真正數值是 3 而不是形式值131 10000011轉換...