浮點數是一種常用的表示數的方式,因小數點可以浮動得名。我們更關心的是在計算機中如何表示浮點數。到目前為止,ieee754統一了浮點數的相關規範,本文也針對於ieee754來進行分析。
在一般的通用計算機中,通常來講單精度浮點數(float)使用32個bit來表示,雙精度(double)使用64個bit來表示。因為單雙精度方法類似,只是表達範圍不同,所以本文以單精度(32bits)為例進行**。
對於單精度浮點數,32位被分為3部分,分別是符號位(1bit),階碼位(8bits),小數字(23bits)。對於浮點數,採用科學計數法的方式來進行數值上的表示。科學計數法也正好對應以上三部分。數值的正負又符號位體現,正數為0,負數為1。根據基數的不同,分為2,8,16進製制等等,但對映到計算機中都是二進位制。對於規格化浮點數來講預設小數點前面的數字都是1,於是可以節省此bit位,不對此進行表示。小數部分對應三大部分中的小數字,直接按照小數點後的順序對應即可。需要注意的就是不夠23位的後面補0。
重點是在階碼位,也是本文的主要講述物件。首先階碼的選擇是移碼而不是補碼。移碼就是設定偏移量的原碼,從數值上來看也是符號位取反的補碼,移碼減去1作為階碼。為什麼選擇移碼而不是補碼呢?因為浮點數中涉及到很多比較的操作,也叫做「對階」(我理解為兩個浮點數比大小,第乙個比的是整體數值的符號,其次就是階的大小),而補碼進行比較,需要先轉換成原碼非常麻煩。所以在這一點上移碼具有強大的優勢。(當然了,可能還有其他的原因,歡迎各位讀者補充)。
為什麼移碼比較時具有優勢呢?可以簡單理解成使用移碼在比較時都是正數,從原碼變成移碼的過程中加上了乙個偏置常數(bias)。偏置常數的作用就是修改浮點數的規格化數階數的表示範圍。以ieee754為例,有8位無符號數來表示階數大小。因為特殊的規定,取消全是1的最大數和全是0的最小數,原因是保留全是1和全是0作為非規格化使用。所以表示範圍是(1至254),共計254個數字。為了表示正負範圍相同,偏置常數為254/2=127。在原來的左右兩側範圍減去127後,表示的範圍就變成(-126~127),以上這是屬於表示階段。當進行真正比較的時候,又重新加上偏置常數,變成正數,利於比較。所以一定要記住減去偏置常數後再用二進位製做表示。
bias的計算公式如下:
在之前的學習過程中,老師留下乙個疑問,為什麼浮點數表示不精確,具體內容可見部落格:link
浮點數階碼為什麼用移碼表示,具體可見部落格:link
對浮點數介紹很詳細(雖然目前沒看懂的):link
2023年3.17更
之前寫這篇的時候還是在學計算機組成原理的時候,學了浮點數的大部分內容。但這學期一門課叫做計算機系統結構又新學了一點關於浮點數的內容,我在此做個補充。
其實之前一直沒有想過階碼、尾數的表示都是二進位制,那用其他進製,比如16進製表示行不行呢?答案當然是:可以!東西的本質不變,表示的方法有很多種。
這裡放一張相關的圖(圖源:計算機系統結構(第五版)-李學幹)
對其中相關的引數進行下說明:
p:階碼除去符號位後的位數(階碼整體使用p+1位表示)
rm:表示的進製數(2,8,16…)
m:2進製下尾數的位數
m』:其他進製下尾數的位數。
那使用比2大的進製有什麼好處壞處呢?
優點:擴大浮點數的表示範圍、增加可表示數的個數、減少移位次數、降低右移造成的精度損失、提高運算速度
缺點:降低資料的表示精度、數值的分布變稀。
此處對於其他進製的介紹比較簡略,起到乙個拋磚引玉的作用(我從來沒想過這個問題),更為詳細的內容請大家參考其他資料。
浮點數 儲存
關鍵字 體系結構 ieee754 浮點數 儲存 main 如果不執行上面的 讓我們來直接判斷,輸出的結果會是什麼?而在你執行程式之後,結果卻很讓人詫異 123.456001。為什麼會是123.456001?有六位小數可以理解,最後那個1是為何?有很多人解釋說最後那個1是亂碼,隨機的。嘿嘿 其實無論你...
浮點數操作
float fx 49.03f int nx fx 100 printf d nx 執行上述 結果 4902。用vc6.0,2005,gcc編譯執行結果都是一樣。為什麼會這樣呢,是因為浮點數運算具有不精確性。其實編譯上面的 編譯器會有警告的。warning c4244 initializing co...
浮點數比較
在數 算當中經常會涉及到判斷兩個數是否相等的情況 對於整數很好處理 a b這樣的乙個語句就可以解決全部的問題 但是對於浮點數是不同的 首先,浮點數在計算機當中的二進位制表達方式就決定了大多數浮點數都是無法精確的表達的 現在的計算機大部分都是數字計算機,不是模擬機,數字機的離散化的資料表示方法自然無法...