![](http://static.javashuo.com/static/loading.gif)
二、用二進制數表示小數
先來一個熱身,把1011.0011這個有小數點的二進制數轉換成十進制數(前面章節已經講過了用二進制來表示整數的方法,其實小數也同樣),以下圖所示:正則表達式
![](http://static.javashuo.com/static/loading.gif)
三、計算機運算出錯的緣由
經過第2節的學習,你們應該也能大概知道計算機運算出錯的緣由了:是由於「有一些十進制數的小數沒法轉換成二進制數」。例如十進制數0.1,就沒法用二進制數正確表示,小數點後面即便有幾百位也沒法表示。編程
咱們就看小數點後4位用二進制數表示時的數值範圍0.0000~0.1111,以下圖所示:
![](http://static.javashuo.com/static/loading.gif)
這裏只能表示0.5 、 0.25 、 0.125 、0.0625這四個二進制數小數點後面的位權組合而成(相加總和)的小數。再回到咱們要表示的0.1,怎麼加都沒法加到0.1的,只會變成0.00011001100...(1100的循環),不信你能夠去試試。編程語言
說到這裏,你們應該都能明白爲何將0.1累加100次也得不到10的緣由了把,由於沒法正確表示的數值,最後都變成了近似值。計算機是一個功能有限的機器設備,是沒法處理無限循環的小數的,通常計算機都會從中間截斷。學習
四、什麼是浮點數
像1011.0011這樣帶小數點的表現形式,徹底是紙面上的二進制數表現形式,在計算機內部是沒法使用的。這一章節主要是說明計算機是以什麼樣的表現形式來處理小數。不少編程語言中都提供了兩種表示小數的數據類型,分別是雙精度浮點數與單精度浮點數。雙精度浮點數類型用64位、單精度浮點數用32位來表示全體小數。從C語言中,雙精度浮點數類型和單精度浮點數類型分別用double和float來表示。3d
浮點數是指符號、尾數、基數和指數這四個部分來表示的小數,以下圖:blog
![](http://static.javashuo.com/static/loading.gif)
由於計算機內部使用的是二進制,因此基數天然就是2.所以,實際的數據中每每不考慮基數,只用符號、尾數、指數這三部分便可表示浮點數。也就是說,64位(雙精度浮點數)和32位(單精度浮點數)的數據,會被分爲三部分來使用,以下圖展現:循環
![](http://static.javashuo.com/static/loading.gif)
① 符號部分:是指使用一個數據位來表示數值的符號。該數據位是1時表示負,爲0時則表示「正或者0」。
② 尾數部分:數值大小的決定部分之一(另一個是指數部分)。尾數部分用的是「將小數點前面的值固定爲1的正則表達式」。
③ 指數部分:用的則是EXCESS系統表現。
五、正則表達式和EXCESS系統
① 尾數部分使用正則表達式,能夠將表現形式多樣的浮點數統一爲一種表現形式。例如十進制的0.75就有不少種表現形式:數據類型
正由於表現形式太多,計算機處理時就會比較麻煩。所以,爲了方便計算機處理,須要制定一個統一的規則。例如,十進制數的浮點數應該遵循「小數點前面是0,小數點後面第1位不能是0」這樣的規則。根據這個規則,0.75就是「0.75 * 10的0次冪」,也就是說,只能用尾數部分是0.7五、指數部分是0這個方法來表示。根據這個規則來表示小數的方式,就是正則表達式。
二進制數也是一樣的道理,在二進制數中,咱們使用的是「將小數點前面的值固定爲1的正則表達式」。具體來說,就是將二進制數表示的小數左移或右移(這裏是邏輯移位。由於符號位是獨立的)數次後,正數部分的第1位變爲1,第2位以後都變爲0(這樣是爲了消除第2位以上的數位)。並且,第1位的1在實際的數據中不保存。因爲第1位必須是1,所以,省略該部分後就節省了一個數據位,從而也就能夠表示更多的數據範圍。
下圖是單精度浮點數的正則表達式的具體例子(單精度浮點數中,尾數部分是23位):
![](http://static.javashuo.com/static/loading.gif)
六、在實際的程序中進行確認
對EXCESS系統與正則表達式瞭解了嗎,若是尚未了解,就返回上一小節再看一看,我也是看了幾遍纔看懂的,若是看懂了,就往下看,用C語言程序來確認單精度浮點數表示方法。二進制
七、如何避免計算機計算出錯
計算機計算出錯的緣由之一是採用浮點數來處理小數(另外,也有因「位溢出」而形成計算錯誤的狀況)。做爲程序的數據類型,不論是使用單精度浮點數仍是雙精度浮點數,都存在計算出錯的可能性。接下來會介紹兩種避免該問題的方法。
① 迴避策略,即無視這個錯誤,只要獲得近似值就能夠了,那些微小的偏差徹底能夠忽略掉。
② 把小數轉換成正數來計算。
八、二進制數和十六進制數
最後補充說明一下二進制數和十六進制數的關係。在實際程序中,若是二進制位數太多,看起來會比較麻煩,所以,在實際程序中,也常常會用十六進制數來代替二進制數。二進制數的4位,正好至關於十六進制數的1位。例如,32位二進制數00111101110011001100110011001101用十六進制數來表示的話,就是3DCCCCCD這個8位數。因而可知,經過使用十六進制數,二進制數的位數可以縮短至原來的1/4 。
用十六進制數來表示二進制小數時,小數點後的二進制數的4位一樣至關於十六進制的1位。不夠4位時用0填補二進制數的低位便可。例如,1011.011的低位補0後爲1011.0110,這時就能夠表示爲十六進制數B.6 。