我的C筆記(一)

2021-10-03 19:03:56 字數 3835 閱讀 2184

計算機內資料的儲存是以二進位制數的補碼形式存在的。

那麼什麼是補碼呢?

這裡要涉及到二進位制數的原碼、反碼、補碼等儲存方式的概念。

機器編碼

機器編碼有原碼、反碼、補碼、移碼、階碼等。

原碼

原碼概念

計算機中所有的二進位制數均用0、1編碼表示,數字的正、負也不例外,如果乙個機器數字長是n的話,約定最左邊1位作為符號位,其餘n-1位用於表示數值。在符號位上,用0表示正,用1表示負。數值位表示真值的絕對值。凡不足n-1位的,小數在最低位右邊增加0;整數則在數值位的最高位(不是符號位)左邊增加0,補足n-1為。這種計算機的編碼形式叫做原碼

原碼的表示形式:符號位+二進位制數值

例如十進位制數12,它的二進位制原碼為[0000 1100],最高位0表示符號+(正)。

有符號的二進位制編碼如下圖所示:

圖 1 8bit機器

例如在8bit的機器內,小數和整數的表示:

小數:[+0.1011]原=0.1011000,補足8位:0

1011

000[-0.1011]原=1.1011000,補足8位:1

1011

000整數:[+1011]原=00001011,補足8位:0

0001

011[-1011]原=10001011,補足8位:1

0001

011**中的小數點只是在書寫時為了清晰可見,在機器中並不出現。

原碼的特徵

◇最高位0表示正,1表示負。其餘二進位制數是該數字的絕對值的二進位制位。

◇原碼簡單易懂,接近人的思維。

例如:我們用8位二進位制表示乙個數,+11的原碼為00001011,-11的原碼就是10001011,這個很好理解。

◇加、減運算複雜,相減時,被減數不夠減時,需要向高位借位。原碼的符號位不能直接參與運算。

乙個字長為n(即n bit)的機器數能表示不同的數字的個數是固定的:2n個,n=8時,2n=256。如果用來表示有符號數,那麼取值範圍是-2n-1~+2n-1。n=8時這個範圍即是-128~127。但是在不考慮數的的正負時,就不需要用1位二進位制數來表示符號位,n位機器數全部用來表示數值,這時表示數的取值範圍是0~2n-1,n=8時的範圍就是0~255。沒有符號位的數,稱為無符號數。

◇存在加、減、乘、除四種運算,增加cpu的複雜度。

◇0的表示不唯一,有+0和-0之分。

反碼

反碼是數值儲存的一種,多應用於系統環境設定,如linux平台的目錄和檔案的預設許可權的設定umask,就是使用反碼原理。

反碼運算不方便,也沒有在計算機中得以應用。

反碼表示法規定

◇正數的反碼與其原碼相同;

[01010]原=[01010]反

◇負數的反碼是對其絕對值正數的原碼逐位取反,取反時包含符號位。

例如,對二進位制數10010的原碼求反碼:

[10010]原碼

=[00010]取正(1.先對原碼取其絕對值。)

=[11101]取反(2.對得到的絕對值取反,取反時包括符號位。)

注意

:其實,求

負數的反碼

,也可以說是負數的原碼符號位不動,其餘取反。

負數原碼的反碼 = ~|負數|,~為取反的意思。

如下:如:原碼10010的反碼可以這樣求得:

[10010]原碼=[11101]反碼----符號位不動,其餘逐位取反。

那麼原碼(10010)2的反碼(11101)2就是表示十進位制數(-2)10。反碼並不是十進位制數在計算機中的二進位制表現形式,在計算機中表示的二進位制數是補碼。那麼什麼是補碼呢?接著往下看。

移碼

表示數值平移n位,n稱為移碼量。移碼主要表示浮點數的階碼的儲存。

補碼

補碼的概念

在計算機系統中,二進位制數值一律用補碼來表示和儲存。

補碼的設計目的是:

◇使符號位能與有效值部分一起參加運算,從而簡化運算規則。

◇補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬體電路。

◇使減法運算轉換為加法運算,進一步簡化計算機中運算器的線路設計,所有這些轉換都是在計算機的最底層進行的。

補碼表示法規定

補碼是由原碼轉化而來,那麼轉化規則是:

◇正數的補碼與其原碼相同。

正數的補碼 = 正數的原碼

(10)10  =[0000 1010]原

=[0000 1010]補

◇負數的補碼是在取其反碼之後加1。

負數的補碼 = 負數原碼的反碼+1

負數原碼的反碼 = ~|負數|

(-10)10 =[1000 1010]原

=[1111 0101]反+[0000 0001]即1

=[1111 0110]補

例題:把十進位制(10)10和(-10)10轉為二進位制補碼表示。

1).如果十進位制數為,如(10)10,那麼:

(10)10=[0000 1010]原

=[0000 1010]反----對於正數,原碼=反碼

=[0000 1010]補----對於正數,反碼=補碼

所以(10)10 在計算機中的二進位制補碼形式為:(0000 1010)2。

總結:如果十進位制數的為,原碼=補碼。原碼即是二進位制數的表示。

2).如果十進位制數符號為,如(-10)10,那麼:

(-10)10=[1000 1010]原

=[1111 0101]反+1

=[1111 0110]補

所以(10)10 在計算機中的二進位制補碼形式為:(1111 0110)2。

總結:如果十進位制數為把原碼取反數,得到反碼,然後把 反碼+1,即是補碼,也就是二進位制補碼在計算機中的表示。(一句話:原碼取反+1)

3).資料的加減法

如:8 - 9 = -1

計算機中不存在減法,減法是負數的加法。也就是把表示資料的二進位制原碼轉為補碼,進行補碼相加

,再把補碼取反。示例過程示例如下:

因為是補碼運算,所以要對十進位制數進行補碼轉換,然後再運算。

8 - 9= 8 + ( -9 )

= [0000 1000]原 + [1000 1001]原

= [0000 1000]反 +( [1111 0110]反+1)

= [0000 1000]補 + [1111 0111]補

= [1111 1111]補----到了這一步,計算機內算是完成了運算,但是我們要看到是十進位制數的結果。所以就需要把補碼再轉為原碼。

以下是還原過程:

設反碼為x反,那麼

x反 =[1111 1111]補-1

= [1111 1110]反----補碼=反碼+1,那麼反碼=補碼-1,再把反碼取反,得到下一步,即原碼:

= [1000 0001]原----再把二進位制

= (-1)10

即8-9=-1。

其實,這個運算的發明遠沒有那麼簡單,這裡還涉及到餘數,補數。暫略,後補。

(無聊)我我我我的C 筆記(一)

我我我要學c 可是我我我只會c。所以,這篇筆記從乙個c初學者的角度。試著理解c 他在狂笑 概念 所以為什麼要有物件導向程式設計?當然,我們寫乙個hello world算乙個2 3是不需要物件導向的,但是當軟體年得越來越大,越來越多的 量的時候。問題就來了 舉個例子,我要做fifa遊戲,額這個遊戲已經...

我的C 筆記

1,map的key值是不能重複的,char 比較的是位址,所以認為key值相同,所以你只能插入乙個元素 若要用char 做key,需要過載操作符 t1,t2 也就是map的第三個引數,當然你用std string做key的話,可以不用過載這個操作符。2,char轉int char a 1 int b...

我的C 筆記

1,map的key值是不能重複的,char 比較的是位址,所以認為key值相同,所以你只能插入乙個元素 若要用char 做key,需要過載操作符 t1,t2 也就是map的第三個引數,當然你用std string做key的話,可以不用過載這個操作符。2,char轉int char a 1 int b...