计组学习笔记(一):浮点数的表示和运算
? 最近學習計算機組成原理,遇到許多疑難問題,接下來寫一寫我在學習浮點數方面知識的理解,在鞏固的同時也方便日后的復習。
一、浮點數的表示
1、浮點數的表示格式
? 浮點數,顧名思義,就是小數點不固定的數。計算機中,根據小數點位置是否固定,分為兩種數據格式,一種就是這個,小數點不固定,另一種是定點數,小數點是固定的。
? 書上科學地對浮點數表示法的定義是,以適當的形式將比例因子表示在數據中,讓小數點的位置根據需要而浮動。我們計算機的容量有限,不可能對每個數都用特別多的位數來表示,比如說2×10^99,這種非常大的數不可能用定點數來表示,所以呢利用浮點數就可以在位數有限的情況下擴大數的表示范圍,同時能保持一定的有效精度。
? 通常情況下,浮點數表示為:N = r^E × M
? 式子里面r是浮點數階碼的底在計算機中是隱含的,通常情況下r=2。E和M都是帶符號的定點數,E叫做階碼,M叫做尾數。其中E的大小越大,能表示的數范圍越大,M的位數越大,數的有效精度越高。
? 簡單地舉一個例子,1.111×2^100這里面1.111就是尾數,100就是階碼,顯然這里階碼占的位數為3位,尾數占的位數是4位,假如階碼占的位數有4位,位數占的位數是3位(階碼和尾數所占位數總和不變),那么這個數就只能表示為1.11×2^0100,顯然能表示的數的范圍變大了,就這個例子來說原來尾數1.111轉變為1.11損失了0.001,這就是精度的損失。
?浮點數的一般格式:
? 這里J是階符,表示階碼的符號,S是數符,表示浮點數的符號,階符J和階碼的m位合起來表示浮點數的表示范圍和小數點的實際位置,n位尾數反映了浮點數的精度。
2、浮點數的規格化
? 為什么要進行浮點數的規格化呢,我們知道了浮點數的一般格式,同一個浮點數可以有很多表現形式,比如1.111×2^3,還可以表示為0.1111×2^4,還可以表示為11.11×2^2,那我們總不能任意地表示一個數吧,另外還有一個問題就是,如果尾數位數只有4位,我們想要表示同一個數1111采取兩種方法,一個是 0.0111x2^5 和 0.1111×2^4(二者最高為是數符位S),我們可以很清晰地看到,如果采用階碼為5的方法,我們損失了一位精度,階碼為4的方法表示這個數更為精確。
? 所以,為了提高運算精度,就要充分利用尾數的有效數位,也就是浮點數的規格化,即規定尾數的最高數位必須是一個有效值。非規格化數轉變為規格化數,轉變過程就是通過調整尾數和階碼的大小,使尾數最高位保證是一個有效值。通常有兩種規格化操作:
? 左規:當浮點數運算結果是非規格化數的時候,要進行規格化操作,將尾數算術左移一位,階碼減1(基數為2時),左規操作可能要進行多次。
? 右規:當浮點數運算結果尾數出現溢出的時候,將尾數算術右移一位,階碼加1。需要右規操作的時候只需要操作一次。
? 規格化浮點數的尾數M的絕對值應該滿足這樣的關系:1/r ≤ |M| ≤ 1(r就是我們的階碼的底,也是基數)。
? 以r=2為例:
? 1、原碼尾數規格化后:正數為0.1xxxxxx形式,最大值為0.11......1;最小值為0.100......0。負數為1.1xxxxxx形式,最大值表示為1.10......0;最小值表示為1.11......1。
? 2、補碼尾數規格化后:正數同原碼正數。負數為1.0xxxxxx形式,最大值表示為1.01......1;最小值表示為1.00......0。
? 需要注意的是基數,剛剛是以基數為2時的規格化形式,補碼規格化數的尾數最高位一定與尾數符號位相反。基數不同的時候,規格化的形式不同,當基數為4時,原碼規格化形式的尾數最高兩位不全為0;基數為8時,原碼規格化形式的尾數最高三位不全為0。
? 如何判斷一個浮點數是否是規格化數:規格化浮點數的尾數小數點后的第一位一定是個非零的數。因此對于原碼編碼的尾數來說,只要看尾數的第一位是否為1就行;對于補碼表示的尾數,只要看符號位和尾數最高位是否相反。(IEEE 754標準的浮點數尾數是用原碼編碼的)
3、IEEE 754標準
? IEEE 754標準采用的浮點數的格式:
? ms為數符,表示浮點數的符號,E為階碼部分,用移碼表示,M是尾數部分,用原碼表示。
? IEEE 754標準規定常用的浮點數格式有短浮點數(單精度、float)、長浮點數(雙精度、double型)、臨時浮點數。
? 短浮點數數符占1位;階碼占8位,以2為底,用移碼表示,階碼偏置值為127(階碼全1表示無限大,E的范圍是1~254,空出全0表示非規格化數);尾數部分為23位。
? 長浮點數數符占1位;階碼占11位,以2為底,用移碼表示,階碼偏置值為1023(階碼全1表示無限大,E的范圍是1~2046,空出全0表示非規格化數);尾數部分為52位。
? 在IEEE754標準中長浮點數和短浮點數的尾數采用隱藏位策略的原碼表示,什么意思呢。舉個例子來說,以短浮點數為例,尾數占23位。我們知道,規格化浮點數后,尾數最高位一定是一位有效值,對于二進制浮點數來說,尾數最高位一定是1,那么我們為了充分利用資源,既然最高位一定是1了,我們干脆就把它隱藏好了,因此尾數實際上是24位,在表示的時候尾數23位是純小數。比如說十進制12(1100),轉化為二進制浮點數規格化后為1.1×2^3,這里我們就把整數部分的1 隱藏了,整數部分的1不存在23位尾數中,存的時候就是這樣的32位:0 ? 1000 0010 ? 1000 0000 0000 0000 0000 000。
二、浮點數的加減運算
? 浮點數運算的特點是階碼運算和尾數運算分開來算。加減運算一律采用補碼。具體運算分為以下幾步。
? 1、對階:對階的目的是讓兩個數小數點的位置看齊,使這兩個數的階碼相等。顯然1.1×2^3和1.1×2^4是不能直接相加減的。原則是小階向大階看齊,像這個例子,就是1.1×2^3的尾數右移一位,階碼加一,直到兩個數的階碼相等。
? 2、尾數求和:階碼對齊之后就可以直接按照定點數的加減法則運算尾數了。
? 3、規格化:尾數求和后的結果如果不是規格化數需要規格化,以雙符號位運算為例的話,如果運算結果為正數,規格化的形式應該是00.1xxx......x,如果運算結果為負數,規格化后的形式應該是11.0xxx......x,不符合這種形式的數要進行左規或者右規的操作讓其變成這種形式。(在尾數沒有溢出的情況下,即尾數結果的雙符號為不是10或01的時候,操作都是左規操作,左規操作可能不止進行一次,倘若雙符號位為01或10則表明尾數已經溢出了,就要進行右規操作,右規只需要進行一次)
? 4、舍入:在對階和右規的操作中,我們都是將尾數右移,階碼加一,由于我們的位數是有限的,在右移的操作過程中很有可能就將低位的尾數丟失了,這會引起誤差和精度問題。常用的減小誤差的方法有“0”舍“1”入法:即在尾數右移時,被移去的最高數值位為0則舍去,如果被移去的最高數值位為1則在尾數末位加1,如果加1之后又產生溢出則再右規操作一次。恒置“1”法:看名字就可以知道,無論丟掉的最高數值位是1還是0,都使右移后的尾數末位置1。這種方法可能使尾數變大或者變小。
? 5、溢出判斷:既然定點數運算可能溢出,浮點數同樣也會溢出,我們已經知道浮點數的表示方法和加減運算規則,既然是溢出,那么肯定是超出了浮點數能表示的范圍,浮點數的范圍主要是由階碼決定的,如果運算結果規格化后階碼產生了溢出,那才是浮點數的溢出。浮點數的溢出與否是由階碼的符號決定的。以雙符號位的補碼為例,如果階碼的符號位出現01或10則說明階碼溢出了,01表示階碼大于最大階碼,上溢,進入中斷處理;10表示階碼小于最下階碼,下溢,按機器零處理。(溢出時真值的符號位和高位符號位保持一致)還要注意的一點是尾數之和(差)可能會造成尾數的溢出,這并不代表整個的溢出,需要右規一次看階碼是否溢出才能判斷。
? 以上便是我學習浮點數的時候結合書與自己的理解做出的總結,例子都是以基數為2時舉的,如果有錯誤還望看出來的小伙伴勿責怪,幫忙指明一下下。
總結
以上是生活随笔為你收集整理的计组学习笔记(一):浮点数的表示和运算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tinyxml c语言,开源TinyXM
- 下一篇: 字符串匹配之KMP---全力解析