基本數據類型
計算機底層存儲數據時使用的是二進制數字,可是計算機在存儲一個數字時並非直接存儲該數字對應的二進制數字,而是存儲該數字對應二進制數字的補碼。因此接下來咱們須要來了解一下原碼、反碼和補碼。微信
- 機器數:一個數在計算機的存儲形式是二進制數,咱們稱這些二進制數爲機器數,機器數是有符號,在計算機中用機器數的最高位存放符號位,0表示正數,1表示負數。
- 機器數的真值:由於帶有符號位,因此機器數的形式值不等於其真值,以機器數1000 0111爲例,其真正表示的值爲-7,而形式值爲135。將帶符號的機器數的真正表示的值稱爲機器數的真值。
原碼
原碼的表示與機器數真值表示的同樣,即用第一位表示符號,其他位表示數值,例如的十進制的的正負1,用8位二進制的原碼錶示以下:編碼
【+1】= 原:[ 0000 0001 ]設計
【-1】= 原:[ 1000 0001 ]內存
反碼
反碼的表示方法爲:class
- 正數的反碼是其原碼自己。
- 負數的反碼是在其原碼的基礎上,符號位不變,其他各位取反。
【+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 ]im
數據在計算機中的存儲形式
計算機實際只存儲補碼, 因此原碼轉換爲補碼的過程,也能夠理解爲數據存儲到計算機內存中的過程:
在原、反、補碼中,正數的表示是如出一轍的,而負數的表示是不相同的,因此對於負數的補碼來講,咱們是不能直接用進制轉換將其轉換爲十進制數值的,由於這樣是得不到計算機真正存儲的十進制數的,因此應該將其轉換爲原碼後,再將轉換獲得的原碼進行進制轉換爲十進制數。(機器數包含符號位)
問題:爲什麼使用原碼、反碼、補碼
咱們上面說過,原碼、反碼、補碼的表示對於正數來講都是同樣的,而對於負數來講,三種碼的表示確是徹底不一樣的,那你們是否會有個疑問:若是原碼纔是咱們人類能夠識別並用於直接計算的表示方式,那爲何還會有反碼和補碼?計算機直接存儲原碼不就完事了?
在解決這些問題前,咱們先來了解計算機的底層概念,咱們人腦能夠很輕鬆的知道機器數的第一位是符號位,但對於計算機基礎電路設計來講判別第一位是符號位是很是難和複雜的事情,爲了讓計算機底層設計更加簡單,人們開始探索將符號位參與運算,而且採用只保留加法的方法,咱們知道減去一個數,等於加上這個數的負數,即:1-1 = 1 + (-1) = 0,這樣讓計算機運算就更加簡單了,而且也讓符號位參與到運算中去。
1.使用原碼運算
計算十進制表達式:1-1 = 0;
1 - 1 = 1 + (-1)
= 原:[ 0000 0001 ] + 原:[ 1000 0001 ]
= 原:[ 1000 0010 ] = -2
若是用原碼錶示,讓符號位也參與計算,對於減法來講,結果是不正確的。這也是計算機內部在存儲數據時不使用原碼的緣由,爲了解決這一問題,出現了反碼。
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。爲了解決這一問題,出現了補碼。
3.使用補碼運算
1 - 1 = 1 + (-1)
= 原:[ 0000 0001 ] + 原:[ 1000 0001 ]
= 補:[ 0000 0001 ] + 補:[ 1111 1111 ]
= 補: [ 0000 0000 ] = 原: [ 0000 0000 ] = 0
這樣0用[0000 0000]表示,而之前出現問題的-0則不存在了,並且人們還發現能夠用[1000 0000]表示-128,-128的推算過程以下:
(-1) + (-127) = -128
= 原:[1000 0001] + 原:[ 1111 1111 ]
= 補:[ 1111 1111 ] + 補:[ 1000 0001 ]
= 補:[ 1000 0000 ]
注意:由於其實是使用之前的-0的補碼來表示-128,因此-128並無原碼和反碼錶示,只要補碼是[1000 0000],其十進制數值就爲-128。
由於補碼能多存儲一個-128,並且在計算機底層中存儲的是補碼,因此在計算機中一個8位的二進制數的存儲範圍是用補碼錶示的[-128,127],而不是用原碼或反碼錶示的[-127,127]。這也能夠解釋爲何計算機中一個字節的取值範圍是[-128,127]。
這樣也可以回答咱們開始提出的問題了,原碼、反碼、補碼的使用,是人們爲了讓符號位能參與運算並讓計算機底層運算更加簡單而設計出來的數據存儲表示方式。
更多精彩內容敬請關注微信公衆號:【平兄聊Java】