第二章數(shù)據(jù)的機器級表示與處理_第1頁
第二章數(shù)據(jù)的機器級表示與處理_第2頁
第二章數(shù)據(jù)的機器級表示與處理_第3頁
第二章數(shù)據(jù)的機器級表示與處理_第4頁
第二章數(shù)據(jù)的機器級表示與處理_第5頁
已閱讀5頁,還剩60頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、第二章第二章 數(shù)據(jù)的機器級表示與處理數(shù)據(jù)的機器級表示與處理數(shù)值數(shù)據(jù)的表示非數(shù)值數(shù)據(jù)的表示數(shù)據(jù)的存儲數(shù)據(jù)的運算數(shù)據(jù)的表示和運算數(shù)據(jù)的表示和運算主要教學(xué)目標(biāo)主要教學(xué)目標(biāo) 掌握計算機內(nèi)部各種數(shù)據(jù)的編碼表示及其運算方法 了解高級語言程序中的各種類型變量對應(yīng)的表示形式 在高級語言程序中的變量、機器數(shù)和底層硬件(寄存器、加法器、ALU等)之間建立關(guān)聯(lián) 綜合運用所學(xué)知識,分析高級語言和機器級語言程序設(shè)計中遇到的各種與數(shù)據(jù)表示和運算相關(guān)的問題,解釋相應(yīng)的執(zhí)行結(jié)果C語言參考網(wǎng)站:http:/ 第一講:數(shù)值數(shù)據(jù)的表示 定點數(shù)的編碼表示、整數(shù)的表示、無符號整數(shù)、帶符號整數(shù)、浮點數(shù)的表示 C語言程序的整數(shù)類型和浮點數(shù)

2、類型 第二講:非數(shù)值數(shù)據(jù)的表示、數(shù)據(jù)的存儲 邏輯值、西文字符、漢字字符 數(shù)據(jù)寬度單位、大端/小端、對齊存放 第三講:數(shù)據(jù)的運算 按位運算邏輯運算移位運算 位擴展和位截斷運算 無符號和帶符號整數(shù)的加減運算 無符號和帶符號整數(shù)的乘除運算 變量與常數(shù)之間的乘除運算 浮點數(shù)的加減乘除運算圍繞C語言中的運算,解釋其在底層機器級的實現(xiàn)從C程序的表達(dá)式出發(fā),用機器數(shù)在電路中的執(zhí)行來解釋表達(dá)式的執(zhí)行結(jié)果課程內(nèi)容概要課程內(nèi)容概要/*-sum.c-*/int sum(int a , unsigned len)int i,sum = 0;for (i = 0; i y and iy) & (i100) th

3、en “!”表示表示“NOT”運算運算 與按位運算的差別與按位運算的差別符號表示不同:符號表示不同:& & ;| ; 運算過程不同:運算過程不同:按位按位 整體整體結(jié)果類型不同:結(jié)果類型不同:位串位串 邏輯值邏輯值C語言程序中涉及的運算語言程序中涉及的運算 移位運算移位運算用途用途提取部分信息提取部分信息擴大或縮小數(shù)值的擴大或縮小數(shù)值的2、4、8倍倍操作操作左移左移::xk不區(qū)分是邏輯移位還是算術(shù)移位,由不區(qū)分是邏輯移位還是算術(shù)移位,由x的類型確定的類型確定無符號數(shù):邏輯左移、邏輯右移無符號數(shù):邏輯左移、邏輯右移高(低)位移出,低(高)位補高(低)位移出,低(高)位補0,可能溢

4、出!,可能溢出!問題:何時可能發(fā)生溢出?如何判斷溢出?問題:何時可能發(fā)生溢出?如何判斷溢出? 若高位移出的是若高位移出的是1,則左移時發(fā)生溢出,則左移時發(fā)生溢出帶符號整數(shù):算術(shù)左移、算術(shù)右移帶符號整數(shù):算術(shù)左移、算術(shù)右移左移:高位移出,低位補左移:高位移出,低位補0??赡芤绯觯?。可能溢出! 溢出判斷:溢出判斷:若移出的位不等于新的符號位,則溢出。若移出的位不等于新的符號位,則溢出。右移:低位移出,高位補符,可能發(fā)生有效數(shù)據(jù)丟失。右移:低位移出,高位補符,可能發(fā)生有效數(shù)據(jù)丟失。如何從如何從1616位數(shù)據(jù)位數(shù)據(jù)y y中提取高位字節(jié)?中提取高位字節(jié)?某字長為某字長為8 8的機器中,的機器中,x x、

5、y y和和z z都是都是8 8位帶符號位帶符號整數(shù),已知整數(shù),已知x=-81x=-81,則,則y=x/2=y=x/2=?z=2x=z=2x=?(y8) 送送8位寄存器位寄存器移位!移位!y= 40? z= 162?C語言程序中涉及的運算語言程序中涉及的運算 位擴展和位截斷運算位擴展和位截斷運算用途用途類型轉(zhuǎn)換時可能需要數(shù)據(jù)擴展或截斷類型轉(zhuǎn)換時可能需要數(shù)據(jù)擴展或截斷操作操作沒有專門操作運算符,根據(jù)類型轉(zhuǎn)換前沒有專門操作運算符,根據(jù)類型轉(zhuǎn)換前后數(shù)據(jù)長短確定是擴展還是截斷后數(shù)據(jù)長短確定是擴展還是截斷擴展:短轉(zhuǎn)長擴展:短轉(zhuǎn)長 無符號數(shù):無符號數(shù):0擴展,前面補擴展,前面補0 帶符號整數(shù):符號擴展,前面

6、補符帶符號整數(shù):符號擴展,前面補符截斷:長轉(zhuǎn)短截斷:長轉(zhuǎn)短 強行將高位丟棄,故可能發(fā)生強行將高位丟棄,故可能發(fā)生“溢出溢出”例例1(擴展操作):在大端機上輸出(擴展操作):在大端機上輸出si, usi, i, ui的十進制和十六進制值是什么?的十進制和十六進制值是什么?short si = -32768;unsigned short usi = si;int i = si;unsingned ui = usi ;si = -32768 80 00usi = 32768 80 00i = -32768 FF FF 80 00 ui = 32768 00 00 80 00例例2(截斷操作):(截斷

7、操作):i和和j是否相等?是否相等?int i = 32768;short si = (short) i;int j = si;不相等!不相等!i = 32768 00 00 80 00si = -32768 80 00 j = -32768 FF FF 80 00原因:對原因:對i i截斷時發(fā)生截斷時發(fā)生了了“溢出溢出”,即:,即:32768截斷為截斷為16位數(shù)時位數(shù)時,因其超出,因其超出16位能表位能表示的最大值,故無法示的最大值,故無法截斷為正確的截斷為正確的16位數(shù)位數(shù)!如何實現(xiàn)高級語言源程序中的運算?如何實現(xiàn)高級語言源程序中的運算? 總結(jié):總結(jié):C語言程序中的基本數(shù)據(jù)類型及其基本運算

8、類型語言程序中的基本數(shù)據(jù)類型及其基本運算類型 基本數(shù)據(jù)類型基本數(shù)據(jù)類型無符號數(shù)、帶符號整數(shù)、浮點數(shù)、位串、字符(串)無符號數(shù)、帶符號整數(shù)、浮點數(shù)、位串、字符(串) 基本運算類型基本運算類型算術(shù)、按位、邏輯、移位、擴展和截斷、匹配算術(shù)、按位、邏輯、移位、擴展和截斷、匹配 計算機如何實現(xiàn)高級語言程序中的運算?計算機如何實現(xiàn)高級語言程序中的運算? 將各類表達(dá)式編譯(轉(zhuǎn)換)為指令序列將各類表達(dá)式編譯(轉(zhuǎn)換)為指令序列 計算機直接執(zhí)行指令來完成運算計算機直接執(zhí)行指令來完成運算例:例:C語言賦值語句語言賦值語句“f = (g+h) (i+j);”中變量中變量i、j、f、g、h由編譯器分別由編譯器分別分配給

9、分配給MIPS寄存器寄存器$t0$t4。寄存器。寄存器$t0$t7的編號對應(yīng)的編號對應(yīng)815,上述程序段對,上述程序段對應(yīng)的應(yīng)的MIPS機器代碼和匯編表示(機器代碼和匯編表示(#后為注釋)如下:后為注釋)如下:000000 01011 01100 01101 00000 100000 add $t5, $t3, $t4 # g+h000000 01000 01001 01110 00000 100000 add $t6, $t0, $t1 # i+j000000 01101 01110 01010 00000 100010 sub $t2, $t5, $t6 # f =(g+h)(i+j) 需

10、要提供哪些運算類指令才能支持高級語言需求呢?需要提供哪些運算類指令才能支持高級語言需求呢?邏輯運算、移位、擴展和截斷等指令實現(xiàn)較容易,算術(shù)運算指令難!n位整數(shù)加位整數(shù)加/減運算器減運算器先看一個C程序段: int x=9, y=-6, z1, z2; z1=x+y; z2=x-y; 問題:上述程序段中,x和y的機器數(shù)是什么?z1和z2的機器數(shù)是 什么?回答:x的機器數(shù)為x補, y的機器數(shù)為y補 ; z1的機器數(shù)為x+y補 ; z2的機器數(shù)為x-y補 。因此,計算機中需要有一個電路,能夠?qū)崿F(xiàn)以下功能:已知 x補 和 y補 ,計算x+y補 和 x-y補 。根據(jù)補碼定義,有如下公式:x+y補 =2n

11、+x+y= 2n+x+2n+y= x補+y補 (mod 2n )x-y補=2n+x-y= 2n+x+2n-y= x補+-y補 (mod 2n )補碼的定義 假定補碼有n位,則:X補=2n +X (-2nX2n ,mod 2n)y補=y補+1n位整數(shù)加位整數(shù)加/減運算器減運算器利用帶標(biāo)志加法器,可構(gòu)造整數(shù)加/減運算器,進行以下運算:無符號整數(shù)加、無符號整數(shù)減帶符號整數(shù)加、帶符號整數(shù)減當(dāng)Sub為1時,做減法當(dāng)Sub為0時,做加法 補碼加減運算公式A+B補 = A補 + B 補 ( mod 2n )AB補 = A補 + B 補 ( mod 2n ) 實現(xiàn)減法的主要工作在于:求B 補問題:如何求B補?

12、B補=B補+1在整數(shù)加/減運算部件基礎(chǔ)上,加上寄存器、移位器以及控制邏輯,就可實現(xiàn)ALU、乘/除運算以及浮點運算電路Sum加法器444AZFCinCout4B401MUXSubBOF整數(shù)加/減運算部件SFCFB算術(shù)邏輯部件(算術(shù)邏輯部件(ALU) 進行基本算術(shù)運算與邏輯運算 無符號整數(shù)加、減 帶符號整數(shù)加、減 與、或、非、異或等邏輯運算 核心電路是整數(shù)加/減運算部件輸出除和/差等,還有標(biāo)志信息有一個操作控制端(ALUop),用來決定ALU所執(zhí)行的處理功能。ALUop的位數(shù)k決定了操作的種類,例如,當(dāng)位數(shù)k為3時,ALU最多只有23=8種操作。ALUop Result ALUop Result

13、ALUop Result ALUop Result 0 0 0 A加B 0 1 0 A與B 1 0 0 A取反 1 1 0 A 0 0 1 A減B 0 1 1 A或B 1 0 1 A B 1 1 1 未用回顧:認(rèn)識計算機中最基本的部件回顧:認(rèn)識計算機中最基本的部件CPU:中央處理器;PC:程序計數(shù)器;MAR:存儲器地址寄存器ALU:算術(shù)邏輯部件;IR:指令寄存器;MDR:存儲器數(shù)據(jù)寄存器GPRs:通用寄存器組(由若干通用寄存器組成) 控制器CPU PC輸入設(shè)備輸出設(shè)備 MAR MDRALU標(biāo)志寄存器 IR地址數(shù)據(jù)控制GPRs0123存儲器01234567所有運算電路的核心所有運算電路的核心Su

14、m加法器nnnAZFCinCoutnBn01多路選擇器SubBOF加加/ /減運算部件減運算部件CF=Co SubSF當(dāng)Sub為1時,做減法當(dāng)Sub為0時,做加法重要認(rèn)識1:計算機中所有算術(shù)運算都基于加法器實現(xiàn)!重要認(rèn)識2:加法器不知道所運算的是帶符號數(shù)還是無符號數(shù)。重要認(rèn)識3:加法器不判定對錯,總是取低n位作為結(jié)果,并生成標(biāo)志信息。溢出標(biāo)志零標(biāo)志符號標(biāo)志進/借位標(biāo)志條件標(biāo)志位(條件碼條件標(biāo)志位(條件碼CC)l 零標(biāo)志ZF、溢出標(biāo)志OF、進/借位標(biāo)志CF、符號標(biāo)志SF稱為條件標(biāo)志。 條件標(biāo)志(Flag)在運算電路中產(chǎn)生,被記錄到專門的寄存器中 存放標(biāo)志的寄存器通常稱為程序/狀態(tài)字寄存器或標(biāo)志寄

15、存器。每個標(biāo)志對應(yīng)標(biāo)志寄存器中的一個標(biāo)志位。 如,IA-32中的EFLAGS寄存器問題:OF=?ZF=? SF=?CF=?還記得如何得到各個標(biāo)志位嗎?OF:若A與B同號但與Sum不同號,則1;否則0。SF:sum符號ZF:如Sum為0,則1,否則0。CF:Cout subSum加法器加法器nnnAZFCinCoutnBn01MuxSelSubBOF整數(shù)加/減運算部件SFCFB問題:為什么要生成并保存條件標(biāo)志?為了在分支指令(條件轉(zhuǎn)移指令)中被用作是否轉(zhuǎn)移執(zhí)行的條件!if (ij) n位帶標(biāo)志加法器位帶標(biāo)志加法器溢出標(biāo)志OF:OF=Cn Cn-1符號標(biāo)志SF:SF=Fn-1零標(biāo)志ZF=1當(dāng)且僅當(dāng)

16、F=0;進位/借位標(biāo)志CF:CF=Cout Cin整數(shù)加法舉例整數(shù)加法舉例若n=8,計算107+46=?進位是真正的符號:+15310710= 0110 10112 4610 = 0010 11102 0 1001 1001溢出標(biāo)志OF=1、零標(biāo)志ZF=0、符號標(biāo)志SF=1、進位標(biāo)志CF=0SumAddernnnAZFCinCoutnBn01MuxSelSubBOF整數(shù)加/減運算部件SFCFB兩個正數(shù)相加,結(jié)果為負(fù)數(shù),故溢出!即OF=1做加法時,主要判斷是否溢出無符號加溢出條件:CF=1帶符號加溢出條件:OF=1無符號:sum=153,因為CF=0,故未發(fā)生溢出,結(jié)果正確! 帶符號:sum=

17、-103,因為OF=1,故發(fā)生溢出,結(jié)果錯誤!整數(shù)減法舉例整數(shù)減法舉例 -7- 6 = -7 + (-6) = +3 -3 - 5 = - 3 + (- 5) = - 8 9 - 6 = 3 13 - 5 = 811+0001111001110111100010001111帶符號 (1) 最高位和次高位的進位不同溢出: (2) 和的符號位和加數(shù)的符號位不同X做減法以比較大小,規(guī)則:Unsigned: CF=0時,大于 Signed:OF=SF時,大于OF=0、ZF=0、SF=1、借位CF=0OF=1、ZF=0SF=0、借位CF=0驗證:96,故CF=0;135,故CF=0驗證:-76,故OFS

18、F -35,故OFSF無符號減溢出:差為負(fù)數(shù),即借位CF=1整數(shù)減法舉例整數(shù)減法舉例無符號和帶符號加減運算都用該部件執(zhí)行unsigned int x=134;unsigned int y=246;int m=x;int n=y;unsigned int z1=x-y;unsigned int z2=x+y;int k1=m-n;int k2=m+n;x和m的機器數(shù)一樣:1000 0110,y和n的機器數(shù)一樣:1111 0110z1和k1的機器數(shù)一樣:1001 0000,CF=1,OF=0,SF=1z1的值為144(=134-246+256,x-y256)k2的值為124(=134+246-25

19、6,m+n128,即正溢出)假定 n=8SumAddernnnAZFCinCoutnBn01MuxSelSubBOFSFCF無符號加公式:帶符號加公式:如何用程序判斷一個無符號數(shù)相加沒有發(fā)生溢出/* Determine whether arguments can be added without overflow */int uadd_ok(unsigned x, unsigned y) unsigned sum = x+y; return sum = x;無符號整數(shù)加法溢出判斷程序無符號整數(shù)加法溢出判斷程序發(fā)生溢出時,一定滿足 resultx and resulty否則,若x+y-2n x,

20、則 y 2n ,這是不可能的!做模擬器實驗時,模擬Add指令需要用!帶符號整數(shù)加法溢出判斷程序帶符號整數(shù)加法溢出判斷程序如何用程序判斷一個帶符號整數(shù)相加沒有發(fā)生溢出 /* Determine whether arguments can be added without overflow */int tadd_ok(int x, int y) int sum = x+y; int neg_over = x 0 & y = 0; int pos_over = x = 0 & y = 0 & sum =0,y=0 x80000000時,該函數(shù)判斷錯誤帶符號整數(shù)加帶符號整數(shù)減帶

21、符號減的溢出判斷函數(shù)如何實現(xiàn)呢?無符號減的溢出判斷函數(shù)又如何實現(xiàn)呢?模擬Sub指令需要!帶符號整數(shù)減法溢出判斷程序帶符號整數(shù)減法溢出判斷程序/* * subOK - Determine if can compute x-y without overflow * Example: subOK(0 x80000000,0 x80000000) = 1, * subOK(0 x80000000,0 x70000000) = 0, * Legal ops: ! & | + * Max ops: 20 * Rating: 3 */int subOK(int x, int y) int diff

22、= x+y+1; int x_neg = x31; int y_neg = y31; int d_neg = diff31; /* Overflow when x and y have opposite sign, and d different from x */ return !(x_neg y_neg) & (x_neg d_neg);整數(shù)的乘運算整數(shù)的乘運算 通常,高級語言中兩個n位整數(shù)相乘得到的結(jié)果通常也是一個n位整數(shù),也即,結(jié)果只取2n位乘積中的低n位。 例如,在C語言中,參加運算的兩個操作數(shù)的類型和結(jié)果的類型必須一致,如果不一致則會先轉(zhuǎn)換為一致的數(shù)據(jù)類型再進行計算。int

23、 mul(int x, int y) int z=x*y; return z;x*y 被轉(zhuǎn)換為乘法指令,在乘法運算電路中得到的乘積是64位,但是,只取其低32位賦給z。整數(shù)的乘運算整數(shù)的乘運算 在計算機內(nèi)部,一定有x2 0嗎?若x是帶符號整數(shù),則不一定!如x是浮點數(shù),則一定!例如,當(dāng) n=4 時, 52=-70 !01010101 01010101 +00011001只取低4位,值為-111B=-7如何判斷返回的z是正確值?當(dāng) !x | z/x=y 為真時什么情況下,乘積是正確的呢?當(dāng) -2n-1 x*y 2n-1 (不溢出)時即:乘積的高n位為全0或全1,并等于低n位的最高位!即:乘積的高n

24、+1位為全0或全1int mul(int x, int y) int z=x*y; return z;若x、y和z都改成unsigned類型,則判斷方式為結(jié)果溢出乘積的高n位為全0,則不溢出整數(shù)的乘運算整數(shù)的乘運算 結(jié)論:假定兩個n位無符號整數(shù)xu和yu對應(yīng)的機器數(shù)為Xu和Yu,pu=xuyu,pu為n位無符號整數(shù)且對應(yīng)的機器數(shù)為Pu;兩個n位帶符號整數(shù)xs和ys對應(yīng)的機器數(shù)為Xs和Ys,ps=xsys,ps為n位帶符號整數(shù)且對應(yīng)的機器數(shù)為Ps。若Xu=Xs且Yu=Ys,則Pu=Ps。 可用無符號乘來實現(xiàn)帶符號乘,但高n位無法得到,故不能判斷溢出。無符號乘法器 XuYuPunnnnpu=xu*

25、yu;帶符號乘法器 XsYsPsnnnnps=xs*ys;PuhPshPuhPsh無符號:若Puh=0,則不溢出帶符號:若Psh每位都等于Ps的最高位,則不溢出整數(shù)的乘運算整數(shù)的乘運算X*Y的高n位可以用來判斷溢出,規(guī)則如下: 無符號:若高n位全0,則不溢出,否則溢出 帶符號:若高n位全0或全1且等于低n位的最高位,則不溢出。整數(shù)的乘運算整數(shù)的乘運算 硬件不判溢出,僅保留2n位乘積,供軟件使用 如果程序不采用防止溢出的措施,且編譯器也不生成用于溢出處理的代碼,就會發(fā)生一些由于整數(shù)溢出而帶來的問題。 指令:分無符號數(shù)乘指令、帶符號整數(shù)乘指令 乘法指令的操作數(shù)長度為n,而乘積長度為2n,例如: I

26、A-32中,若指令只給出一個操作數(shù)SRC,則另一個源操作數(shù)隱含在累加器AL/AX/EAX中,將SRC和累加器內(nèi)容相乘,結(jié)果存放在AX(16位時)或DX-AX(32位時)或EDX-EAX(64位時)中。 在MIPS處理器中,mult會將兩個32位帶符號整數(shù)相乘,得到的64位乘積置于兩個32位內(nèi)部寄存器Hi和Lo中,因此,可以根據(jù)Hi寄存器中的每一位是否等于Lo寄存器中的第一位來進行溢出判斷。乘法指令可生成溢出標(biāo)志,編譯器可使用2n位乘積來判斷是否溢出!整數(shù)乘法溢出漏洞整數(shù)乘法溢出漏洞以下程序存在什么漏洞,引起該漏洞的原因是什么。 /* 復(fù)制數(shù)組到堆中,count為數(shù)組元素個數(shù) */int cop

27、y_array(int *array, int count) int i; /* 在堆區(qū)申請一塊內(nèi)存 */ int *myarray = (int *) malloc(count*sizeof(int); if (myarray = NULL) return -1; for (i = 0; i count; i+) myarrayi = arrayi; return count; 當(dāng)參數(shù)count很大時,則count*sizeof(int)會溢出。如count=230+1時, count*sizeof(int)=4。堆(heap)中大量數(shù)據(jù)被破壞!攻擊者可構(gòu)造特殊參數(shù)來觸發(fā)整數(shù)溢出,以一段預(yù)設(shè)

28、信息覆蓋一個已分配的堆緩沖區(qū),造成遠(yuǎn)程服務(wù)器崩潰或者改變內(nèi)存數(shù)據(jù)并執(zhí)行任意代碼。2002年,Sun Microsystems公司的RPC XDR庫帶的xdr_array函數(shù)發(fā)生整數(shù)溢出漏洞,攻擊者可利用該漏洞從遠(yuǎn)程或本地獲取root權(quán)限。變量與常數(shù)之間的乘運算變量與常數(shù)之間的乘運算 整數(shù)乘法運算比移位和加法等運算所用時間長,通常一次乘法運算需要多個時鐘周期,而一次移位、加法和減法等運算只要一個或更少的時鐘周期,因此,編譯器在處理變量與常數(shù)相乘時,往往以移位、加法和減法的組合運算來代替乘法運算。 例如,對于表達(dá)式x*20,編譯器可以利用20=16+4=24+22,將x*20轉(zhuǎn)換為(x4)+(x2

29、=0000 0011 -12/4=-3:1111 0100 2=1111 1101 不能整除時,右移移出的位中有非0,需要進行相應(yīng)處理變量與常數(shù)之間的除運算變量與常數(shù)之間的除運算 不能整除時,采用朝零舍入,即截斷方式 無符號數(shù)、帶符號正整數(shù)(地板):移出的低位直接丟棄 帶符號負(fù)整數(shù)(天板):加偏移量(2k-1),然后再右移k 位 ,低位截斷(這里K 是右移位數(shù)) 舉例: 無符號數(shù) 14/4=3:0000 11102=0000 0011 帶符號負(fù)整數(shù) -14/4=-3 若直接截斷,則 1111 0010 2=1111 1100=-4-3 應(yīng)先糾偏,再右移: k=2, 故(-14+22-1)/4=

30、-3 即: 1111 0010+0000 0011=1111 0101 1111 01012=1111 1101=-3假設(shè)x為一個int型變量,請給出一個用來計算x/32的值的函數(shù)div32。要求不能使用除法、乘法、模運算、比較運算、循環(huán)語句和條件語句,可以使用右移、加法以及任何按位運算。解:若x為正數(shù),則將x右移k位得到商;若x為負(fù)數(shù),則x需要加一個偏移量(2k-1)后再右移k位得到商。因為32=25,所以 k=5。 即結(jié)果為: ( x=0 ? x : (x+31)5 但題目要求不能用比較和條件語句,因此要找一個計算偏移量b的方式 這里,x為正時b=0,x為負(fù)時b=31. 因此,可以從x的符

31、號得到b x31 得到的是32位符號,取出最低5位,就是偏移量b。 變量與常數(shù)之間的除運算變量與常數(shù)之間的除運算舉例舉例 int div32(int x) /* 根據(jù)x的符號得到偏移量b */ int b=(x31) & 0 x1F; return (x+b)5; 浮點數(shù)運算及結(jié)果浮點數(shù)運算及結(jié)果設(shè)兩個規(guī)格化浮點數(shù)分別為 A=Ma . 2Ea B=Mb.2Eb ,則: A+B =(Ma + Mb.2-(Ea-Eb). 2Ea (假設(shè)Ea=Eb )A*B =(Ma * Mb).2Ea+EbA/B =(Ma / Mb).2Ea-Eb上述運算結(jié)果可能出現(xiàn)以下幾種情況:階碼上溢:一個正指數(shù)超過

32、了最大允許值 =+/-/溢出階碼下溢:一個負(fù)指數(shù)比最小允許值還小 =+0/-0尾數(shù)溢出:最高有效位有進位 =右規(guī)非規(guī)格化尾數(shù):數(shù)值部分高位為0 =左規(guī)右規(guī)或?qū)﹄A時,右段有效位丟失 =尾數(shù)舍入 IEEE建議實現(xiàn)時為每種異常情況提供一個自陷允許位。若某異常對應(yīng)的位為1,則發(fā)生相應(yīng)異常時,就調(diào)用一個特定的異常處理程序執(zhí)行。SP最大指數(shù)為多少? 127SP最小指數(shù)呢?-126-23運算過程中添加保護位尾數(shù)溢出,結(jié)果不一定溢出1.5+1.5=?1.5-1.0=?浮點數(shù)除浮點數(shù)除0的問題的問題為什么整數(shù)除0會發(fā)生異常?為什么浮點數(shù)除0不會出現(xiàn)異常?這是網(wǎng)上的一個帖子浮點運算中,一個有限數(shù)除以0,結(jié)果為正無

33、窮大(負(fù)無窮大)浮點數(shù)加浮點數(shù)加/ /減運算減運算 十進制科學(xué)計數(shù)法的加法例子 1.123 105 + 2.560 102 其計算過程為:1.123 105 + 2.560 102 = 1.123 105 + 0.002560 105 =(1.123 + 0.00256) 105 = 1.12556 105 =1.126 105 “對階”操作:目的是使兩數(shù)階碼相等 小階向大階看齊,階小的那個數(shù)的尾數(shù)右移,右移位數(shù)等于兩個階碼差的絕對值 IEEE 754尾數(shù)右移時,要將隱含的“1”移到小數(shù)部分,高位補0,移出的低位保留到特定的“附加位”上進行尾數(shù)加減運算前,必須“對階”!最后還要考慮舍入計算機內(nèi)

34、部的二進制運算也一樣!浮點數(shù)加減法基本要點浮點數(shù)加減法基本要點 (假定:Xm、Ym分別是X和Y的尾數(shù), Xe和Ye 分別是X和Y的階碼 )(1) 求階差:e=Ye Xe (若Ye Xe,則結(jié)果的階碼為Ye)(2) 對階:將Xm右移e位,尾數(shù)變?yōu)?Xm*2Xe-Ye(保留右移部分附加位)(3) 尾數(shù)加減: Xm*2Xe-Ye Ym(4) 規(guī)格化: 當(dāng)尾數(shù)高位為0,則需左規(guī):尾數(shù)左移一次,階碼減1,直到MSB為1或階碼為00000000(-126,非規(guī)格化數(shù)) 每次階碼減1后要判斷階碼是否下溢(比最小可表示的階碼還要?。?當(dāng)尾數(shù)最高位有進位,需右規(guī):尾數(shù)右移一次,階碼加1,直到MSB為1 每次階碼

35、加1后要判斷階碼是否上溢(比最大可表示的階碼還要大)如果尾數(shù)比規(guī)定位數(shù)長(有附加位),則需考慮舍入(有多種舍入方式)(5) 若運算結(jié)果尾數(shù)是0,則需要將階碼也置0。為什么?階碼溢出異常處理:階碼上溢,則結(jié)果溢出;階碼下溢到無法用非規(guī)格化數(shù)表示,則結(jié)果為0尾數(shù)為0說明結(jié)果應(yīng)該為0(階碼和尾數(shù)為全0)。0.000001x2-126浮點數(shù)加法運算舉例浮點數(shù)加法運算舉例 例:用二進制浮點數(shù)形式計算 0.5 +( 0.4375) =?對 階: -1.110 x 2-2 -0.111 x 2-1 加 減: 1.000 x 2-1 +( -0.111 x 2-1 ) = 0.001 x 2-1 左 規(guī): 0

36、.001 x 2-1 1.000 x 24判溢出: 無解:0.5 = 1.000 x 2-1, - 0.4375 = -1.110 x 2-2結(jié)果為: 1.000 x 24 = 0.0001000 = 1/16 = 0.0625問題:為何IEEE 754 加減運算右規(guī)時最多只需一次?因為即使是兩個最大的尾數(shù)相加,得到的和的尾數(shù)也不會達(dá)到4,故尾數(shù)的整數(shù)部分最多有兩位,保留一個隱含的“1”后,最多只有一位被右移到小數(shù)部分。0.4375=0.25+0.125+0.0625=0.0111BExtra Bits(附加位附加位)Floating Point numbers are like piles

37、of sand; every time you move one you lose a little sand, but you pick up a little dirt.“浮點數(shù)就像一堆沙,每動一次就會失去一點沙,并撿回一點 臟” 如何才能使失去的“沙” 和撿回的“臟”都盡量少呢?加多少附加位才合適?IEEE754規(guī)定: 中間結(jié)果須在右邊加2個附加位 (guard & round) Guard (保護位):在significand右邊的位 Round (舍入位):在保護位右邊的位Add/Sub: 1.xxxxx 1.xxxxx 1.xxxxx 1.xxxxxxxx + 1.xxxx

38、x 0.001xxxxx 0.01xxxxx -1.xxxxxxxx 1x.xxxxy 1.xxxxxyyy 1x.xxxxyyy 0.00 xxxx附加位的作用:用以保護對階時右移的位或運算的中間結(jié)果。附加位的處理: 左規(guī)時被移到significand中; 作為舍入的依據(jù)。在后面加附加位!無法給出準(zhǔn)確的答案!Rounding Digits(舍入位舍入位)舉例:若十進制數(shù)最終有效位數(shù)為 3,采用兩位附加位(G、R)。 2.3400 * 10 0.0253 * 10 2.3653 * 10222IEEE Standard: four rounding modes(用圖說明)round to ne

39、arest (default) round towards plus infinity (always round up)round towards minus infinity (always round down)round towards 0round to nearest: round digit 1/2 then round up (末位加1) = 1/2 then round to nearest even digit(最近偶數(shù)) 可以證明默認(rèn)方式得到的平均誤差最小。稱為就近舍入到偶數(shù)問題:若沒有舍入位,采用就近舍入到偶數(shù),則結(jié)果是什么?結(jié)果為2.36!精度沒有2.37高!IEEE

40、 754的舍入方式的說明的舍入方式的說明 IEEE 754的舍入方式 ( Z1和Z2分別是結(jié)果Z的最近的可表示的左、右兩個數(shù) ) (1) 就近舍入:舍入為最近可表示的數(shù) 非中間值:0舍1入; 中間值:強迫結(jié)果為偶數(shù)-慢 (2) 朝+方向舍入:舍入為Z2(正向舍入) (3) 朝-方向舍入:舍入為Z1(負(fù)向舍入) (4) 朝0方向舍入:截去。正數(shù):取Z1; 負(fù)數(shù):取Z2 00ZZ1Z2例如:附加位為01:舍11:入10:(強迫結(jié)果為偶數(shù)) 例:1.110111 1.1110; 1.110101 1.1101; 1.110110 1.1110; 1.111110 10.0000; 浮點數(shù)舍入舉例浮點

41、數(shù)舍入舉例例:將同一實數(shù)分別賦值給單精度和雙精度類型變量,然后打印輸出。#include main() float a;double b;a = 123456.789e4;b = 123456.789e4;printf(“%f/n%f/n”,a,b);運行結(jié)果如下:1234567936.0000001234567890.000000問題:為什么同一個實數(shù)賦值給float型變量和double型變量,輸出結(jié)果會有所不同呢?為什么float情況下輸出的結(jié)果會比原來的大?這到底有沒有根本性原因還是隨機發(fā)生的?為什么會出現(xiàn)這樣的情況?float可精確表示7個十進制有效數(shù)位,后面的數(shù)位是舍入后的結(jié)果,舍入

42、后的值可能會更大,也可能更小非規(guī)格化浮點數(shù)舉例非規(guī)格化浮點數(shù)舉例計算器2-63264討論問題:計算器上算的準(zhǔn)確嗎?為什么 x 輸出為 0?為什么 y 的輸出發(fā)生變化?為什么x、y、z用%x輸出為0?Z 輸出為 0 說明了什么?如下賦初值對否? float x=0 x40000000; float y=0 x5f800000;當(dāng)結(jié)果為 0.1x2-126 時,是用非規(guī)格化數(shù)表示還是近似為0?以下程序試圖計算 2-63/264=2-127非規(guī)格化浮點數(shù)舉例非規(guī)格化浮點數(shù)舉例2-162-15z和m的輸出結(jié)果說明了什么?當(dāng)結(jié)果為 0.1x2-126 時,用非規(guī)格化數(shù)表示,而不是近似表示成0!C語言中的

43、浮點數(shù)類型語言中的浮點數(shù)類型 C語言中有float和double類型,分別對應(yīng)IEEE 754單精度浮點數(shù)格式和雙精度浮點數(shù)格式 long double類型的長度和格式隨編譯器和處理器類型的不同而有所不同,IA-32中是80位擴展精度格式 從int轉(zhuǎn)換為float時,不會發(fā)生溢出,但可能有數(shù)據(jù)被舍入 從int或 float轉(zhuǎn)換為double時,因為double的有效位數(shù)更多,故能保留精確值 從double轉(zhuǎn)換為float和int時,可能發(fā)生溢出,此外,由于有效位數(shù)變少,故可能被舍入 從float 或double轉(zhuǎn)換為int時,因為int沒有小數(shù)部分,所以數(shù)據(jù)可能會向0方向被截斷Carnegie

44、 Mellon浮點數(shù)比較運算舉例浮點數(shù)比較運算舉例 對于以下給定的關(guān)系表達(dá)式,判斷是否永真。x = (int)(float) xx = (int)(double) xf = (float)(double) fd = (float) df = -(-f);2/3 = 2/3.0d 0.0 (d*2) f -f -dd * d = 0.0 x*x=0(d+f)-d = fint x ;float f ;double d ;Assume neitherd nor f is NaN否是是否是否是是是自己寫程序測試一下!否否IEEE 754 的范圍和精度的范圍和精度 單精度浮點數(shù)(float型)的表示范

45、圍多大?最大的數(shù)據(jù): +1.111X 2127 雙精度浮點數(shù)(double型)呢? 以下關(guān)系表達(dá)式是否永真? if ( i = (int) (float) i) ) printf (“true”); if ( f = (float) (int) f) ) printf (“true”); 浮點數(shù)加法結(jié)合律是否正確? x = 1.5 x 1038, y = 1.5 x 1038, z = 1.0 (x+y)+z = (1.5x1038+1.5x1038 ) +1.0 = 1.0 x+(y+z) = 1.5x1038+ (1.5x1038+1.0) = 0.0How about double? H

46、ow about double?True!Not always true!約 +3.4 X 1038約 +1.8 X 10308Not always true!False!FALSE!舉例:舉例:Ariana火箭爆炸火箭爆炸 1996年6月4日,Ariana 5火箭初次航行,在發(fā)射僅僅37秒鐘后,偏離了飛行路線,然后解體爆炸,火箭上載有價值5億美元的通信衛(wèi)星。 原因是在將一個64位浮點數(shù)轉(zhuǎn)換為16位帶符號整數(shù)時,產(chǎn)生了溢出異常。溢出的值是火箭的水平速率,這比原來的Ariana 4火箭所能達(dá)到的速率高出了5倍。在設(shè)計Ariana 4火箭軟件時,設(shè)計者確認(rèn)水平速率決不會超出一個16位的整數(shù),但在設(shè)

47、計Ariana 5時,他們沒有重新檢查這部分,而是直接使用了原來的設(shè)計。 在不同數(shù)據(jù)類型之間轉(zhuǎn)換時,往往隱藏著一些不容易被察覺的錯誤,這種錯誤有時會帶來重大損失,因此,編程時要非常小心。舉例:愛國者導(dǎo)彈定位錯誤舉例:愛國者導(dǎo)彈定位錯誤1991年2月25日,海灣戰(zhàn)爭中,美國在沙特阿拉伯達(dá)摩地區(qū)設(shè)置的愛國者導(dǎo)彈攔截伊拉克的飛毛腿導(dǎo)彈失敗,致使飛毛腿導(dǎo)彈擊中了一個美軍軍營,殺死了美軍28名士兵。其原因是由于愛國者導(dǎo)彈系統(tǒng)時鐘內(nèi)的一個軟件錯誤造成的,引起這個軟件錯誤的原因是浮點數(shù)的精度問題。 愛國者導(dǎo)彈系統(tǒng)中有一內(nèi)置時鐘,用計數(shù)器實現(xiàn),每隔0.1秒計數(shù)一次。程序用0.1的一個24位定點二進制小數(shù)x來乘

48、以計數(shù)值作為以秒為單位的時間這個x的機器數(shù)是多少呢?0.1的二進制表示是一個無限循環(huán)序列:0.000110011,x=0.000 1100 1100 1100 1100 1100B。顯然,x是0.1的近似表示,0.1-x = 0.000 1100 1100 1100 1100 1100 1100 - 0.000 1100 1100 1100 1100 1100B,即為: =0.000 0000 0000 0000 0000 0000 1100 1100B =2-200.1 9.5410-8這就是機器值與真值之間的誤差!舉例:愛國者導(dǎo)彈定位錯誤舉例:愛國者導(dǎo)彈定位錯誤 已知在愛國者導(dǎo)彈準(zhǔn)備攔截飛毛腿導(dǎo)彈之前,已經(jīng)連續(xù)工作了100小時,飛毛腿的速度大約為2000米/秒,則由于時鐘計算誤差而導(dǎo)致的距離誤差是多少? 100小時相當(dāng)于計數(shù)了100606010=36105次,因而導(dǎo)彈的時鐘已經(jīng)偏差了9.5410-836105 0.343秒 因此,距離誤差是20000.343秒 687米小故事:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論