正文

正數的補碼(正數的補碼怎么求)

shiyingbao

正數的補碼(正數的補碼怎么求)

馮·諾依曼體系結構

  1. 計算機處理的數據和指令一律用二進制數表示

  2. 順序執行程序 計算機運行過程中,把要執行的程序和處理的數據首先存入主存儲器(內存),計算機執行程序時,將自動地并按順序從主存儲器中取出指令一條一條地執行,這一概念稱作順序執行程序。

  3. 計算機硬件由運算器、控制器、存儲器、輸入設備和輸出設備五大部分組成。

數據的機內表示

二進制表示

  1. 機器數 由于計算機中符號和數字一樣,都必須用二進制數串來表示,因此,正負號也必須用0、1來表示。 用最高位0表示正、1表示負, 這種正負號數字化的機內表示形式就稱為“機器數”,而相應的機器外部用正負號表示的數稱為“真值”,將一個真值表示成二進制字串的機器數的過程就稱為編碼。

  2. 原碼 原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值. 比如如果是8位二進制: [+1]原 = 0000 0001 [-1]原 = 1000 0001 第一位是符號位. 因為第一位是符號位, 所以8位二進制數的取值范圍就是: [1111 1111 , 0111 1111] 即 [-127 , 127] 原碼是人腦最容易理解和計算的表示方式

  3. 反碼 反碼的表示方法是: 正數的反碼是其本身 負數的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反. [+1] = [00000001]原 = [00000001]反 [-1] = [10000001]原 = [11111110]反 可見如果一個反碼表示的是負數, 人腦無法直觀地看出來它的數值. 通常要將其轉換成原碼再計算

  4. 補碼 補碼的表示方法是: 正數的補碼就是其本身 負數的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最后+1。 (即在反碼的基礎上+1) [+1] = [00000001]原 = [00000001]反 = [00000001]補 [-1] = [10000001]原 = [11111110]反 = [11111111]補 對于負數, 補碼表示方式也是人腦無法直觀看出其數值的. 通常也需要轉換成原碼在計算其數值.

  5. 定點數與浮點數 定點數是小數點固定的數。在計算機中沒有專門表示小數點的位,小數點的位置是約定默認的。一般固定在機器數的最低位之后,或是固定在符號位之后。前者稱為定點純整數,后者稱為定點純小數。 定點數表示法簡單直觀,但是數值表示的范圍太小,運算時容易產生溢出。

浮點數是小數點的位置可以變動的數。為增大數值表示范圍,防止溢出,采用浮點數表示法。浮點表示法類似于十進制中的科學計數法。

在計算機中通常把浮點數分成階碼和尾數兩部分來表示,其中階碼一般用補碼定點整數表示,尾數一般用補碼或原碼定點小數表示。為保證不損失有效數字,對尾數進行規格化處理,也就是平時所說的科學記數法,即保證尾數的最高位為1,實際數值通過階碼進行調整

階符表示指數的符號位、階碼表示冪次、數符表示尾數的符號位、尾數表示規格化后的小數值。

N = 尾數×基數階碼(指數)

位(Bit)、字節(Byte)、字(Word)

位:”位(bit)”是電子計算機中最小的數據單位。每一位的狀態只能是0或1。

字節:8個二進制位構成1個”字節(Byte)”,它是存儲空間的基本計量單位。1個字節可以儲存1個英文字母或者半個漢字,換句話說,1個漢字占據2個字節的存儲空間。

字:”字”由若干個字節構成,字的位數叫做字長,不同檔次的機器有不同的字長。例如一臺8位機,它的1個字就等于1個字節,字長為8位。如果是一臺16位機,那么,它的1個字就由2個字節構成,字長為16位。字是計算機進行數據處理和運算的單位。

字節序

字節順序是指占內存多于一個字節類型的數據在內存中的存放順序,通常有小端、大端兩種字節順序。

小端字節序指低字節數據存放在內存低地址處,高字節數據存放在內存高地址處;

大端字節序是高字節數據存放在低地址處,低字節數據存放在高地址處。

基于X86平臺的PC機是小端字節序的,而有的嵌入式平臺則是大端字節序的。所有網絡協議也都是采用big endian的方式來傳輸數據的。所以有時我們也會把big endian方式稱之為網絡字節序。

比如數字0x12345678在兩種不同字節序CPU中的存儲順序如下所示:

Big Endian低地址                                            高地址---------------------------------------------------->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|     12     |      34    |     56      |     78    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Little Endian低地址                                            高地址---------------------------------------------------->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|     78     |      56    |     34      |     12    |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

從上面兩圖可以看出,采用Big Endian方式存儲數據是符合我們人類的思維習慣的。

聯合體union的存放順序是所有成員都從低地址開始存放,利用該特性,就能判斷CPU對內存采用Little-endian還是Big-endian模式讀寫。

示例代碼如下:

union test{  
    short  i;  
    char str[sizeof(short)];  
}tt;  

void main()  {  
    tt.i = 0x0102;  
    if(sizeof(short) == 2)  
        {  
            if(tt.str[0] == 1 && tt.str[1] == 2)  
                printf("大端字節序");  
            else if(tt.str[0] = 2 && tt.str[1] == 1)  
                printf("小端字節序");  
            else  
                printf("結果未知");  
         }  
    else  
        printf("sizof(short)=%d,不等于2",sizeof(short));  
}

字節對齊

現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定類型變量的時候經常在特定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。

  • 為什么要進行字節對齊? 某些平臺只能在特定的地址處訪問特定類型的數據; 最根本的原因是效率問題,字節對齊能提?存取數據的速度。

比如有的平臺每次都是從偶地址處讀取數據,對于一個int型的變量,若從偶地址單元處存放,則只需一個讀取周期即可讀取該變量,但是若從奇地址單元處存放,則需要2個讀取周期讀取該變量。

  • 字節對齊的原則 數據成員對齊規則:結構(struct)(或聯合(union))的數據成員,第一個數據成員放在 offset 為0的地方,以后每個數據成員存儲的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是數組,結構體等)的整數倍開始(比如int在32位機為4字節,則要從4的整數倍地址開始存儲。 結構體作為成員:如果一個結構里有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始存儲。(struct a里存有struct b,b里有char,int ,double等元素,那b應該從8的整數倍開始存儲。) 收尾工作:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。