正數(shù)的補碼(正數(shù)的補碼怎么求)
計算機處理的數(shù)據(jù)和指令一律用二進制數(shù)表示 順序執(zhí)行程序 計算機運行過程中,把要執(zhí)行的程序和處理的數(shù)據(jù)首先存入主存儲器(內存),計算機執(zhí)行程序時,將自動地并按順序從主存儲器中取出指令一條一條地執(zhí)行,這一概念稱作順序執(zhí)行程序。 計算機硬件由運算器、控制器、存儲器、輸入設備和輸出設備五大部分組成。 機器數(shù) 由于計算機中符號和數(shù)字一樣,都必須用二進制數(shù)串來表示,因此,正負號也必須用0、1來表示。 用最高位0表示正、1表示負, 這種正負號數(shù)字化的機內表示形式就稱為“機器數(shù)”,而相應的機器外部用正負號表示的數(shù)稱為“真值”,將一個真值表示成二進制字串的機器數(shù)的過程就稱為編碼。 原碼 原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值. 比如如果是8位二進制: [+1]原 = 0000 0001 [-1]原 = 1000 0001 第一位是符號位. 因為第一位是符號位, 所以8位二進制數(shù)的取值范圍就是: [1111 1111 , 0111 1111] 即 [-127 , 127] 原碼是人腦最容易理解和計算的表示方式 反碼 反碼的表示方法是: 正數(shù)的反碼是其本身 負數(shù)的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反. [+1] = [00000001]原 = [00000001]反 [-1] = [10000001]原 = [11111110]反 可見如果一個反碼表示的是負數(shù), 人腦無法直觀地看出來它的數(shù)值. 通常要將其轉換成原碼再計算 補碼 補碼的表示方法是: 正數(shù)的補碼就是其本身 負數(shù)的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最后+1。 (即在反碼的基礎上+1) [+1] = [00000001]原 = [00000001]反 = [00000001]補 [-1] = [10000001]原 = [11111110]反 = [11111111]補 對于負數(shù), 補碼表示方式也是人腦無法直觀看出其數(shù)值的. 通常也需要轉換成原碼在計算其數(shù)值. 定點數(shù)與浮點數(shù) 定點數(shù)是小數(shù)點固定的數(shù)。在計算機中沒有專門表示小數(shù)點的位,小數(shù)點的位置是約定默認的。一般固定在機器數(shù)的最低位之后,或是固定在符號位之后。前者稱為定點純整數(shù),后者稱為定點純小數(shù)。 定點數(shù)表示法簡單直觀,但是數(shù)值表示的范圍太小,運算時容易產(chǎn)生溢出。 浮點數(shù)是小數(shù)點的位置可以變動的數(shù)。為增大數(shù)值表示范圍,防止溢出,采用浮點數(shù)表示法。浮點表示法類似于十進制中的科學計數(shù)法。 在計算機中通常把浮點數(shù)分成階碼和尾數(shù)兩部分來表示,其中階碼一般用補碼定點整數(shù)表示,尾數(shù)一般用補碼或原碼定點小數(shù)表示。為保證不損失有效數(shù)字,對尾數(shù)進行規(guī)格化處理,也就是平時所說的科學記數(shù)法,即保證尾數(shù)的最高位為1,實際數(shù)值通過階碼進行調整 階符表示指數(shù)的符號位、階碼表示冪次、數(shù)符表示尾數(shù)的符號位、尾數(shù)表示規(guī)格化后的小數(shù)值。 N = 尾數(shù)×基數(shù)階碼(指數(shù)) 位:”位(bit)”是電子計算機中最小的數(shù)據(jù)單位。每一位的狀態(tài)只能是0或1。 字節(jié):8個二進制位構成1個”字節(jié)(Byte)”,它是存儲空間的基本計量單位。1個字節(jié)可以儲存1個英文字母或者半個漢字,換句話說,1個漢字占據(jù)2個字節(jié)的存儲空間。 字:”字”由若干個字節(jié)構成,字的位數(shù)叫做字長,不同檔次的機器有不同的字長。例如一臺8位機,它的1個字就等于1個字節(jié),字長為8位。如果是一臺16位機,那么,它的1個字就由2個字節(jié)構成,字長為16位。字是計算機進行數(shù)據(jù)處理和運算的單位。 字節(jié)順序是指占內存多于一個字節(jié)類型的數(shù)據(jù)在內存中的存放順序,通常有小端、大端兩種字節(jié)順序。 小端字節(jié)序指低字節(jié)數(shù)據(jù)存放在內存低地址處,高字節(jié)數(shù)據(jù)存放在內存高地址處; 大端字節(jié)序是高字節(jié)數(shù)據(jù)存放在低地址處,低字節(jié)數(shù)據(jù)存放在高地址處。 基于X86平臺的PC機是小端字節(jié)序的,而有的嵌入式平臺則是大端字節(jié)序的。所有網(wǎng)絡協(xié)議也都是采用big endian的方式來傳輸數(shù)據(jù)的。所以有時我們也會把big endian方式稱之為網(wǎng)絡字節(jié)序。 比如數(shù)字0x12345678在兩種不同字節(jié)序CPU中的存儲順序如下所示: 從上面兩圖可以看出,采用Big Endian方式存儲數(shù)據(jù)是符合我們人類的思維習慣的。 聯(lián)合體union的存放順序是所有成員都從低地址開始存放,利用該特性,就能判斷CPU對內存采用Little-endian還是Big-endian模式讀寫。 示例代碼如下: 現(xiàn)代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定類型變量的時候經(jīng)常在特定的內存地址訪問,這就需要各種類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。 為什么要進行字節(jié)對齊? 某些平臺只能在特定的地址處訪問特定類型的數(shù)據(jù); 最根本的原因是效率問題,字節(jié)對齊能提?存取數(shù)據(jù)的速度。 比如有的平臺每次都是從偶地址處讀取數(shù)據(jù),對于一個int型的變量,若從偶地址單元處存放,則只需一個讀取周期即可讀取該變量,但是若從奇地址單元處存放,則需要2個讀取周期讀取該變量。 字節(jié)對齊的原則 數(shù)據(jù)成員對齊規(guī)則:結構(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個數(shù)據(jù)成員放在 offset 為0的地方,以后每個數(shù)據(jù)成員存儲的起始位置要從該成員大小或者成員的子成員大?。ㄖ灰摮蓡T有子成員,比如說是數(shù)組,結構體等)的整數(shù)倍開始(比如int在32位機為4字節(jié),則要從4的整數(shù)倍地址開始存儲。 結構體作為成員:如果一個結構里有某些結構體成員,則結構體成員要從其內部最大元素大小的整數(shù)倍地址開始存儲。(struct a里存有struct b,b里有char,int ,double等元素,那b應該從8的整數(shù)倍開始存儲。) 收尾工作:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數(shù)倍,不足的要補齊。馮·諾依曼體系結構
數(shù)據(jù)的機內表示
二進制表示
位(Bit)、字節(jié)(Byte)、字(Word)
字節(jié)序
Big Endian低地址 高地址---------------------------------------------------->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| 12 | 34 | 56 | 78 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Little Endian低地址 高地址---------------------------------------------------->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| 78 | 56 | 34 | 12 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
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("大端字節(jié)序");
else if(tt.str[0] = 2 && tt.str[1] == 1)
printf("小端字節(jié)序");
else
printf("結果未知");
}
else
printf("sizof(short)=%d,不等于2",sizeof(short));
}
字節(jié)對齊