C語言 原始碼 反碼 補碼

2021-08-25 13:22:18 字數 4541 閱讀 8373

大家都知道資料在計算機中都是按位元組來儲存了,1個位元組等於8位(1byte=8bit),而計算機只能識別0和1這兩個數,所以根據排列,1個位元組能代表256種不同的資訊,即28

(0和1兩種可能,8位排列),比如定義乙個位元組大小的無符號整數(unsigned char),那麼它能表示的是0~255(0~28-1)這些數,一共是256個數,因為,前面說了,乙個位元組只能表示256種不同的資訊。別停下,還是乙個位元組的無符號整數,我們來進一步剖析它,0是這些數中最小的乙個,我們先假設它在計算機內部就用8位二進位制表示為00000000(從理論上來說也可以表示成其他不同的二進位製碼,只要這256個數每個數對應的二進位製碼都不相同就可以了),再假設1表示為00000001,2表示為00000010,3表示為00000011,依次類推,那麼最大的那個數255在8位二進位制中就表示為最大的數11111111,然後,我們把這些二進位製碼換算成十進位制看看,會發現剛好和我們假設的數是相同的,而事實上,在計算機中,無符號的整數就是按這個原理來儲存的,所以告訴你乙個無符號的整數的二進位製碼,你就可以知道這個數是多少,而且知道在計算機中,這個數本身就是以這個二進位製碼來儲存的。比如我給你乙個2個位元組大小的二進位製碼,首先宣告它表示的是無符號的整數:00000000 00000010,我們把前面的0省略,換算一下,它表示的也是數值2,和前面不同的是,它佔了2個位元組的記憶體。不同的型別佔的記憶體空間不同,如在我的電腦中char是1個位元組,int是4個位元組,long是8個位元組(你的可能不同,這取決於不同的計算機設定),它們的不同之處僅僅是記憶體大的能表示的不同的資訊多些,也就是能表示的數範圍更大些(unsigned int能表示的範圍是0~28*4-1),至於怎麼算,其實都是一樣的,直接把二進位制與十進位制相互轉換,二進位制就是它在計算機中的樣子,十進位制就是我們所表示的數(誤解:不同的計算機儲存的原理是不同的,取決於商家的

喜好呢)。無符號的整數根本就沒有原碼、反碼和補碼。

只有有符號的整數才有原碼、反碼和補碼的!其他的型別一概沒有。雖然我們也可以用二進位制中最小的數去對應最小的負數,最大的也相對應,但是那樣不科學,下面來說說科學的方法。還是說乙個位元組的整數,不過這次是有符號的啦,1個位元組它不管怎麼樣還是只能表示256個數,因為有符號所以我們就把它表示成範圍:-128-127。它在計算機中是怎麼儲存的呢?可以這樣理解,用最高位表示符號位,如果是0表示正數,如果是1表示負數,剩下的7位用來儲存數的絕對值的話,能表示27

個數的絕對值,再考慮正負兩種情況,27*2還是256個數。首先定義0在計算機中儲存為00000000,對於正數我們依然可以像無符號數那樣換算,從00000001到01111111依次表示1到127。那麼這些數對應的二進位製碼就是這些數的原碼。到這裡很多人就會想,那負數是不是從10000001到11111111依次表示-1到-127,那你發現沒有,如果這樣的話那麼一共就只有255個數了,因為10000000的情況沒有考慮在內。實際上,10000000在計算機中表示最小的負整數,就是這裡的-128,而且實際上並不是從10000001到11111111依次表示-1到-127,而是剛好相反的,從10000001到11111111依次表示-127到-1。負整數在計算機中是以補碼形式儲存的,補碼是怎麼樣表示的呢,這裡還要引入另乙個概念——反碼,所謂反碼就是把負數的原碼(負數的原碼和和它的絕對值所對應的原碼相同,簡單的說就是絕對值相同的數原碼相同)各個位按位取反,是1就換成0,是0就換成1,如-1的原碼是00000001,和1的原碼相同,那麼-1的反碼就是11111110,而補碼就是在反碼的基礎上加1,即-1的補碼是11111110+1=11111111,因此我們可以算出-1在計算機中是按11111111儲存的。總結一下,計算機儲存有符號的整數時,是用該整數的補碼進行儲存的,0的原碼、補碼都是0,正數的原碼、補碼可以特殊理解為相同,負數的補碼是它的反碼加1。下面再多舉幾個例子,來幫助大家理解!

十進位制 → 二進位制  (怎麼算?要是不知道看計算機基礎的書去)

47   → 101111

有符號的整數  原碼  反碼  補碼

4700101111

00101111

00101111(正數補碼和原碼、反碼相同,不能從字面理解)

-4710101111

11010000

11010001(負數補碼是在反碼上加1,符號位不參與運算)

再舉個例子,學c語言的同學應該做過這道題:

把-1以無符號的型別輸出,得什麼結果?(程式如下)

#include

void main()

{short int n=-1;

cout<<(unsigned short int)n<

首先在我的電腦中short int型別的儲存空間是2個位元組,你的可能不同,我說過,這取決於你的計算機配置。它能儲存28*2

=65536個不同的資料資訊,如果是無符號那麼它的範圍是0~65535(0~216-1),如果是有符號,那麼它的範圍是-32768~32767(-215~215-1)。這道題目中,開始n是乙個有符號的短整型變數,我們給它賦值為-1,根據我們前面所說的,它在計算機中是以補碼11111111 11111111儲存的,注意前面說了是2個位元組。如果把它強制為無符號的短整型輸出的話,那麼我們就把剛才的二進位制把看成無符號的整型在計算機中儲存的形式,對待無符號的整型就沒有什麼原碼、反碼和補碼的概念了,直接把11111111 11111111轉化成十進位制就是65535,其實我們一看都是一就知道它是範圍中最大的乙個數了。呵呵,就這麼簡單。你個把上面的源**編譯執行看看,如果你的電腦short int也是兩個位元組,那就會和我得一樣的結果。你可以先用這個語句看看:cout《看看你的電腦裡的短整型佔多少的儲存空間,也可以用sizeof來看其它任何型別所分配的儲存空間。

最後提醒一句,關於資料如何在計算機中儲存的,這裡只適用於整型的資料,對於浮點型的是另一種方式,這裡我們暫時就不深究了。

feedback:

1.為什麼使用補碼形式:

其實計算機中的數值用補碼來表示,一是為了防止0有2個編碼,其次就是為了把減法運算用加法運算表示出來,以達到簡化電路的作用。具體內容請參看一些專業書籍,比如華中科技大出版的《邏輯設計》(呵呵,我大二的課本)。

為什麼用補碼表示有符號整數。比如8位整數表示的範圍是-128~127,而不是-127~128呢?想過沒有,為什麼二進位制10000000在原碼和反碼中表示0,在補碼中它不表示0,保證了0表示的唯一性,但是它為什麼表示負數,而不是整數,你也許會說,因為它符號位是1呀,表示負數呀,對,繼續,+128我們用補碼怎麼表示,包括符號位,表示為010000000,超過了2個位元組,如果擷取低8位,那麼是10000000,最高位(符號位)是1,表示的是乙個負數,我們再看看-128的機器碼是多少,原碼110000000,反碼101111111,補碼110000000,擷取低8位即10000000,表示的是乙個負數。

其實呀,這些總結出來的東西都是玩巧,也並不是說非要這樣實現,學了計算機邏輯原理,就知道,其實這樣做是由於物理條件關係。因為運算器裡這樣做更容易實現計算。 2.

int x=-70;

int y=2;

int z=x>>y

z的值是多少?主要是不明白負數移位該怎麼算?

在c語言中int 是兩個位元組所以70在計算機中表示為0000 0000 0100 0110

-70用補碼表示即1111 1111 1011 1010

右移2位c語言中採用的是算術右移

所以補進製和原符號位相同即1111 1111 1110 1110

取反加一求它的相反數0000 0000 0001 0010 等於17

所以右移後的結果是-17

有個規則如果左移1位相當於乘以2 右移1位相當於除以2 取整

我們驗證一下用-70除以2*2 結果取整正好是我們推算的-17

在c++中int 是四個位元組但是結果也是一樣的原因自己可以推算一下

3. 在8位運算中65-15具體怎麼通過補碼計算啊~~~

15的原碼是0000 1111 補碼也是0000 1111

因為是正數符號位(最高位)為0

-15的原碼是1000 1111(←注意這個地方你弄錯了)符號為為1表示負

反碼就是1111 0000(注意原碼反碼補碼之間轉換的時候千萬不要把符號位考慮進去) 補碼就是1111 0001

如果你已經求出了15的補碼這裡有個簡便的方法求-15的補碼:

直接把15的補碼包含符號位一起求反即可即

15補碼1111 0001 那麼-15的補碼0000 1110

補碼計算的時候符號位是要直接參與二進位制運算了而不是單獨考慮

所謂多餘8位的進製捨去其實就是比如補碼1111 1111再加任意非0數原來這個補碼表示的數就會發生溢位(比如加上0000 0001原先符號位1表示負數加後表示正數)

這裡也許你覺得沒有必要因為本身只能容納8位多餘的當然要捨去

可是你可能不知道如果是反碼進行運算的話不是捨去多餘進製而是把多餘的進製加到最低位稱為迴圈進製

4。補碼溢位如何處理

這就要看你處理資料的範圍,比如我用8位二進位制記錄資料。

只能儲存-128~127之間的資料,如果超過127或小於-128就會溢位。

比如127+1=-128 就是這個道理

就好象最大值和最小值連成了乙個環,超過了迴圈計算

這樣做才使得資料有規律性和週期性

為了實現這個所以 補碼是捨掉進製 而反碼是迴圈進製 前面說過了

解決的辦法就是 如果8位的資料不過你就用16位的

如果 整型不夠就用長整型撒 實在不行就用浮點型的

原始碼 補碼 反碼

原始碼 補碼 反碼 大家都知道資料在計算機中都是按位元組來儲存了,1個位元組等於8位 1byte 8bit 而計算機只能識別0和1這兩個數,所以根據排列,1個位元組能代表256種不同的資訊,即28 0和1兩種可能,8位排列 比如定義乙個位元組大小的無符號整數 unsigned char 那麼它能表示...

原始碼,反碼,補碼

字長8位的補碼範圍是 128 127,128的補碼是10000000,0的補碼是000000,這些都是定義規定的,不能用一般的計算方法得出 補碼的設計目的是 使符號位能與有效值部分一起參加運算,從而簡化運算規則.使減法運算轉換為加法運算,進一步簡化計算機中運算器的線路設計 1 原碼 反碼和補碼的表示...

原始碼 補碼 反碼

大家都知道資料在計算機中都是按位元組來儲存了,1個位元組等於8位 1byte 8bit 而計算機只能識別0和1這兩個數,所以根據排列,1個位元組能代表256種不同的資訊,即2 8 0和1兩種可能,8位排列 比如定義乙個位元組大小的無符號整數 unsigned char 那麼它能表示的是0 255 0...