一、進制運算基本知識
1、進制運算的基礎
Ⅰ 進制的概述
進制的定義:進位制是一種計數方式,也稱進位計數法或位值計數法,
常見的進制:二進制、八進制、十進制、十六進制(因為計算機其實就是高低電平,0/1開關,所以計算機喜歡 2 進制,但是因為進制太小,表達一個大的數據的時候二進制表達就特別長,我們使用大進制位就可以解決這個問題,八進制、十六進制滿足2的n次方的要求,自然就成為計算機表示數據的首選了);
Ⅱ 二進制運算的基礎

注意:指數就是從右往左從0開始第幾個數字的意思,前面的系數就是該位置對應的數值,底數就是當前的進制位數;




注意:這也是為什么 0.3 不能用計算機精確表示,而 0.5 可以的原因;
二、二進制數據的表示方法
1、有符號數和無符號數
使用一個符號位(約定數字位的最前面是符號位),0表示正數,1表示負數;
注意:這里如果用源碼表示法的話,那么就出現了兩個 0,即 +0 和 -0 ,例如只有兩位來表示的話,00 即 +0,10 即 -0,但是其實不管是 +0 還是 -0 其實都是0,這樣就存在歧義了,並且原碼表示法進行運算的時候非常復雜,特別是兩個操作數符號的時候;
- 判斷兩個操作數絕對值的大小;
- 使用絕對值大的數減去絕對值小的數;
- 對應符號值,以絕對值大的為准;
於是引入了補碼和反碼來使不同操作數的運算更加簡單;
2、二進制的反碼表示法
- 正數的補碼和反碼都是自己的本身;
- 負數的反碼是將自己除過符號位以外取反;
3、二進制的補碼表示法
使用正數來代替負數的方法,使用加法來代替減法,從而消除減法;
- 正數的補碼和反碼都是自己的本身;
- 負數的補碼是將反碼+1;

規律總結:
- 負數的反碼等於原碼除符號位外按位取反;
- 負數的補碼等於反碼+1;

4、小數的二進制補碼表示
- 正小數的反碼和補碼都是自己;
- 負小數的補碼等於反碼+1;

三、二進制數據的計算
1、定點數與浮點數
- 小數點固定在某個位置的數稱為定點數

如果我們需要表示的數既不是純小數也不是純整數,那我們就需要乘以比例因子以滿足定點數保存格式(浮點數);
- 小數點位置不固定的數稱為浮點數(比如 3.145625×10⁶ 也可以表示為 31456.25×10² 或者 3145.625×10³);
㈠ 浮點數的表示方法
Ⅰ 浮點數的表示格式

尾數必須使用純小數,尾數可以為負數;
階碼的計算:左移一位階碼減一,右移階碼加一。
Ⅱ 浮點數的表示范圍




Ⅲ 浮點數的規格化
- 尾數規定使用純小數;
- 尾數最高位必須是1;(即必須是 0.1XXXXXX的形式)

上述階碼的算法是:x左移了三位,即階碼為 -3 ,3的二進制即為 11 ;
2、定點數的加減法運算

例1:A = -110010,B = 001101,求A+B ;A[補] = 1,001110B[補] = B[原] = 0,001101A[補] + B[補] = (A+B)[補] = 1,011011那么 A+B = (A+B)[補]-1的結果取反:A+B = 1,100101 = - 100101
例2:A = -0.1010010,B = 0.0110100,求 A+B ;A[補] = 1,1.0101110B[補] = B[原] = 0,0.01101001,1.01011100,0.0110100-----------------1,1.1100010A[補] + B[補] = (A+B)[補] = 1,1.1100010注意:十進制的時候借一位+10,二進制借一位+2(A+B)[反] = (A+B)[補]-1 = 1,1.1100001(A+B)[原] = (A+B)[反]取反 = 1,0.0011110 = -0.0011110例3:A = -10010000,B = -01010000,求 A+B ;A[補] = 1,01110000B[補] = 1,101100001,011100001,10110000--------------11,00100000 //去掉多出來的符號位進位 1,00100000A[補] + B[補] = (A+B)[補] = 1,00100000(A+B)[反] = 1,00011111(A+B)[原] = 1,11100000 = -11100000例4:A = -10010000,B = -11010000,求 A+B;A[補] = 1,01110000B[補] = 1,001100001,011100001,00110000------------------10,10100000 //去掉多出來的符號位進位 0,10100000A[補] + B[補] = (A+B)[補] = 0,10100000A+B = 10100000注意:A = -144,B = -208,但是 A+B = 160,這就是溢出,結果無效
判斷溢出
- 雙符號位判斷法:單符號位表示變成雙符號位:0 ==> 00,1 ==> 11,雙符號位產生的進位丟失,結果的雙符號位不同則表示溢出;
使用雙符號位判斷溢出(例4):11,0111000011,00110000------------------110,10100000 //去掉多出來的符號位進位,10,10100000,結果符號位不同,有溢出
例5:A = 11001000,B = -00110100,求 A-B;
A[補] = 0,11001000B[補] = 1,11001100(-B)[補] = 0,00110100A[補] - B[補] = A+(-B)[補]00,1100100000,00110100----------------00,11111100A+(-B)[補] = 0,11111100A - B = 111111100
注意:-B[補]等於B[補]連同符號位按位取反,末位+1;
3、浮點數的加減法運算
步驟:
- 對階:使得兩個浮點數的階碼一致,使得尾數可以進行運算(浮點數尾數運算簡單,浮點數的位數實際小數位與階碼有關,所以階碼按小階看齊大階的原則對其,以便於運算);
- 尾數求和:使用補碼進行運算,減法轉化為加法運算;
- 尾數規格化:一般情況下都需要左移,但是當雙符號位不一致的時候就需要右移(定點運算的溢出情況),右移的話則需要進行舍入操作;

- 舍入:0舍1入法(二進制的四舍五入法,比如S[補] = 10.10110111,s[補] = 11.01011011(1)(右移一位,有階碼的時候階碼要+1),我們右移之后把后面那個1擠沒了,所以需要在這個結果上進行+1操作,即得到 11.01011100,0舍1入的意思就是后面被擠掉的那個數字是0還是1,是0就不管了,是1還要+1的),這種方法可以大大提高浮點數結果的精度,但是這樣也會存在溢出問題 ;
- 溢出判斷:例如s[補] = 01.11111111,這時候需要右移,得到 s[補] = 00.11111111(1),這個時候擠掉一個1,需要進行+1操作,得到 s[補] = 01.00000000,這個時候得到的結果雙符號位還是不一致的,還需要右移,得到s[補] = 00.10000000(0),擠掉一個0,不用管,這個時候兩次右移,階碼需要+2;
x = 0.1101 × 2⁰¹,y = (-0.1010)×2¹¹對階:x = 0.001101×2¹¹,y = (-0.1010)×2¹¹,因為尾數值要對其,所以舍棄掉多余的尾數部分,x = 0.0011×2¹¹尾數求和:x[原] = 00.0011,x[補] = 00.0011;y[原] = 11.1010,y[補] = 11.0110;尾數和S = (x+y)[補] = 11.1001;尾數的規格化:S不滿足規格化,需要左移1位:S = 11.0010左移之后,階碼需要-1,即由 11(3)變為 10(2)x+y[原] = -0.1110×2¹⁰
溢出判斷
浮點數運算主要通過階碼的雙符號位判斷是否溢出,如果規格化之后,階碼雙符號位不一致,則認為是溢出
4、浮點數的乘除法運算
- 乘法:階碼相加,尾數求積;
- 除法:階碼相減,尾數求商;
例1:x = 0.11010011 × 2¹¹⁰¹,y = 0.11101110 × 2⁰⁰⁰¹,假設階碼4位,尾數8位,求 x×yx×y = (0.11010011 × 0.11101110) × 2¹¹¹⁰= 0.11000100 × 2¹¹¹⁰
拉拉
