我們都知道在計算機內部資料的儲存和運算都採用二進位制,是因為計算機是由很多電晶體組成的,而電晶體只有2種狀態,恰好可以
用二進位制的0和1表示,並且採用二進位制可以使得計算機內部的運算規則簡單,穩定性高。在計算機中存在實數和整數,而整數又分
為無符號整數和有符號整數,無符號的整數表示很簡單,直接採用其二進位制形式表示即可,而對於有符號數的表示卻成了問題,如
何表示正負?如何去處理正負號?下面來具體說下其中的原因,在這之前先了解一下原碼、反碼和補碼這幾個概念。
給出幾例子加以說明有符號數的原碼、反碼和補碼
(最高位**符號位)
一、原碼即正數的原碼、反碼和補碼都和原碼相同,負數的原碼為其本身絕對值的原理的最高位加1,反碼是保持最高符號位1不變,其它位取反,補碼是保持最高符號位1不變,反碼加1求原碼:x≥0,則符號位為0,其餘照抄;
x≤0,則符號位為1,其餘照抄。
【例1】x=+100 1001 [x]原 = 0 100 1001
【例2】x=-100 1001 [x]原 = 0 100 1001
二、反碼
求反碼:若x≥0,符號位為0,其餘照抄;
若x≤0,符號位為1,其餘按位取反。
【例3】x=+100 1001 [x]反 = 0 100 1001
【例4】x=-100 1001 [x]反 = 1 011 0110
三、補碼
求補碼:若x≥0,符號位為0,其餘照抄;
若x≤0,符號位為1,其餘取反後,最低位加1。
【例5】x=+1001001 [x]補 = 0 100 1001
【例6】x=-1001001 [x]補 = 1 011 0110(反) + 1 = 1 011 0110
。 1.原碼、反碼和補碼的概念
在了解原碼、反碼和補碼之前先說一下有符號數和無符號數。用過c語言的都知道在c語言中用signed和unsigned來標識乙個數
是否是有符號還是無符號型別的。對於乙個8bit的二進位制來說,若當做無符號數處理,其能表示的整型值範圍是0~255,但是這樣表
示資料就有個侷限性,如果資料是負的該如何表示?因此就引入了有符號型別的概念,對於有符號型別,規定取最高位為符號位,
若最高位為0,則為正數,否則為負數,這樣一來對於有符號的8位二進位制,實際的數值就只有7位了,能夠表示的非負數值範圍變為
0~127,負值範圍為-127~-1。事實上,在計算機內部儲存中,計算機自己是無法去區分無符號還是有符號型別的,因為它是補碼的
形式進行儲存的,對於255和-1,在計算機內部儲存的都是11111111(因為它們的補碼都為11111111)。換個角度來說,如果事先知
道記憶體中儲存了這樣乙個8位二進位制11111111,但是誰也不能肯定它具體表示什麼數值,是-1還是255?這個是需要靠程式設計師自己去
指定的,如果指定為無符號型別,則編譯器則通過相應指令將其轉換為數值255。事實上對於-x的二進位制補碼表示形式和(256-x)(256-x當做無符號型別處理)的二進位制表示形式相同,從這裡可以略微了解了補碼的含義了。在教材中對於原碼、反碼以及補碼一般是這麼定義的:
對於正數原碼、反碼以及補碼是其本身。負數的原碼是其本身,反碼是對原碼除符號位之外的各位取反,補碼則是反碼加1。
因為(-x)的二進位制補碼形式和256-x的二進位制表示形式相同,而255-x相當於對x的每一位取反,那麼256-x就是255-x後加1。
注意:1)原碼、反碼、補碼的概念是針對有符號型別而言的。
2)實數始終是有符號型別的(實數並不是採用補碼形式儲存的,具體可參考《**c/c++的浮點數在記憶體中的儲存方式》一文),整型資料報括無符號和有符號型別的。
2.採用補碼表示帶符號的整數的原因
對於有符號型別的整數,有原碼、反碼和補碼三種形式,最後選擇了補碼來表示,具體來說有下面幾點原因。
1)能夠統一+0和-0的表示
採用原碼表示,+0的二進位制表示形式為0 000 0000,而-0的二進位制表示形式為1 000 0000;
採用反碼表示,+0的二進位制表示形式為0 000 0000,而-0的二進位制表示形式為1 111 1111;
採用補碼表示,+0的二進位制表示形式為0 000 0000,而-0的二進位制表示形式為1 111 1111+1=1 0000 0000,因為計算機會進行截斷,只取低8位,所以-0的補碼表示形式為0000 0000。
從上面可以看出只有用補碼表示,+0和-0的表示形式才一致。正因為如此,所以補碼的表示範圍比原碼和反碼表示的範圍都要大,用補碼能夠表示的範圍為-128~127,0~127分別用00000000~01111111來表示,而-127~-1則用10000001~11111111來表示,多出的10000000則用來表示-128。因此對於任何乙個n位的二進位制,假若表示帶符號的整數,其表示範圍為-2^(n-1)~2^(n-1)-1,且有max+1=min。看下面一段**:
char ch=127;
ch++;
ch的值是多少?它的值是-128,讀者可以上機驗證一下。
假如不採用補碼來表示,那麼計算機中需要對+0和-0區別對待,顯然這個對於設計來說要增加難度,而且不符合運算規則。
2)對於有符號整數的運算能夠把符號位同數值位為一起處理
由於將最高位作為符號位處理,不具有實際的數值意義,那麼如何在進行運算時處理這個符號位?如果單獨把符號位進行處理,顯然又會增加電子器件的設計難度和cpu指令設計的難度,但是採用補碼能夠很好地解決這個問題。下面舉例說明:
比如-2+3=1
如果採用原碼表示(把符號位同數值位一起處理):
1 000 0010+0 000 0011=1 000 0101=(-5)原,顯然這個結果是錯誤的。
如果採用反碼表示
1 111 1101+0 000 0011=1 0000 0000=0 0000000=(+0)反,顯然這個結果也是錯誤的。
如果採用補碼表示
1 111 1110+0 000 0011=1 0000 0001=0000 0001=(1)補,結果是正確的。
從上面可以看出,當把符號位同數值位一起進行處理時,只有補碼的運算才是正確的。如果不把符號位和數值位一起處理,會給cpu指令的設計帶來很大的困難,如果把符號位單獨考慮的話,cpu指令還要特意對最高位進行判斷,這個對於計算機的最底層實現來說是很困難的。
3)能夠簡化運算規則
對於-2+3=1這個例子來說,可以看作是3-2=1,也即[3]+[-2]=1,從上面的運算過程可知採用補碼運算相當於是
[3]補+[-2]補=[1]補,也即可以把減法運算轉換為加法運算。這樣一來的好處是在設計電子器件時,只需要設計加法器即可,不需要單獨再設計減法器。
總的來說,採用補碼主要有以上幾點好處,從而使得計算機從硬體設計上更加簡單以及簡化cpu指令的設計。
測試**
#include
int main(void)
出處:
計算機中的數學符號
計算機中的數學符號 18 03 25 優先順序 求商 求餘思想 數學公式 數學建模 例 輸出4567821的個位上的數字 例 輸出56789的個位上的數字 計算機獲取任何數的個位數 任何數除以10的餘數即個位 例 輸出56789的萬位 最高位 上的數字 計算機獲取任何數的最高位 五位數 除以1000...
談談計算機中的整數
前言 整形長度 整數在記憶體中的儲存形式 整形儲存的原理 整數是從小學就開始學習的內容,作為程式設計師,整形是平時玩的最不亦樂乎的東西。這篇博文,內容基本都在大學計算機基礎書本 現,這裡就算做個人筆記,加深記憶 以c語言為例,整形是int。一般占用4個位元組,即可以表示2 32個數字,大約43億。雖...
計算機中整數的加減運算
通常在程式設計時,會預設將指標以及位址等說明為無符號整數,故其遵循無符號整數的加減運算。在其他情況下面,通常都是進行帶符號的整數運算,但是這兩種運算的本質其實是相通的,因為在計算機內部,這些有無符號整數的加減或者乘除操作其實都是通過相同的加法器來完成的 在加法器內部通過輸入進行判斷是輸出無符號還是有...