Competitive Programming Note
本文已停止更新,新版請至 WiwiHo 的競程筆記
浮點數(也就是小數)的儲存方式是由 IEEE 754 來規範。
簡單來說,浮點數是用類似科學記號的方式來儲存,只是換成二進位而已。用來儲存一個浮點數的記憶體由高位(左)到低位(右)被分成三段:
0
表示此數為正,1
表示此數為負。若指數域所表示的指數值是 ,而小數域表示的值是 ,那麼這個浮點數是: 至於是正或負,依符號位而定。並且 。
在指數域的部分,大家都知道科學記號的指數可能是負的,但這裡並不是按二補數的規則來處理正負,而是規定一個「指數偏移量」,將欲表示的指數加上指數偏移量後,才是儲存在記憶體裡的數字。若指數偏移量是 ,且指數域有 個位元,則可表示的指數範圍是 ,至於 和 被用作特殊用途,等等會介紹。
因為小數域的長度是有限的,但小數有無限小數,無限小數中又有循環小數和無理數,因此會發生不精確的問題,造成計算和判斷上的錯誤,遇到這種狀況有這幾種辦法:
因為浮點數利用科學計號的方式儲存一個數,因此它除了可以表示分數以外,也可以表示一個極大的整數,但要注意它的有效位數並不比 long long
之類的整數結構來得長。
資料型態 | 指數域長度(bit) | 指數偏移量 | 小數域長度(bit) |
---|---|---|---|
float | 8 | 127 | 23 |
double | 11 | 1023 | 52 |
前面有提到當 位指數域的指數偏移量是 時, 和 用於表示特殊值,而特殊值如下:
指數為 的浮點數,符號位為正表示 ,為負則為 。因為一般小數域只儲存小數點後的位數,也就是自動默認小數點前有一個 ,因此 這個數字必須要用特殊值來存。至於正零跟負零唯一的差別在於負零輸出的時候會有負號,我不知道要怎樣才會算出負零就是了。
指數為 ,小數域為 0
,符號位為正表示正無窮,為負表示負無窮,需要它的話,在 C++ 中可以用 INFINITY
來得到,它在 math.h
裡面,只是在競程上沒啥用途,頂多就是除以 會出現無窮,可以幫你 debug。
Not a Number 的縮寫,指數為 ,小數域不是 0
,在反三角函數丟一些超出定義域的數字時會跑出這東西。