C語言之浮點數的存儲
- 2020 年 2 月 19 日
- 筆記
歡迎關注VxWorks567
如轉發,請標明出處!
C語言中,有兩種類型的浮點數:32位的float和64位的double,而在電腦中存儲的是用二進位的科學計數法(即基數為2)表示的值
例如100=1100100B=1.1001B*26,123.456=1111011.0111010010111100011010100111111011111001110111B=1.1110110111010010111100011010100111111011111001110111B*26

既然基數固定為2,尾數的整數部分固定為1,那存儲時就可以省略掉它倆了,只需要存儲另外三個資訊:正負符號+指數+尾數的小數部分
float:符號佔1位,指數佔8位,尾數小數佔23位;
double:符號佔1位,指數佔11位,尾數小數佔52位
不過指數也有正負,因此存儲時加個偏移來表示。float用8位表示指數,偏移就是127;double用的是11位,那偏移就是1023
看看123.456用float是如何存儲的:因為是正數,符號位用0;指數是6,加上偏移127後,133=10000101B;尾數的小數部分的前23位是11101101110100101111001(第24位是1,因此需要進位),拼接成32位數就是01000010111101101110100101111001B=1123477881

將C語言中的定義轉換為彙編驗證一下

再看一個純小數的存儲,例如0.00123456,這次倒著推導一下

電腦中存儲的是983683318,轉換為二進位就是00111010101000011101000011110110B。其中第一個0表示正值;挨著的8位01110101B=117,表示指數為(117-127)=-10;最後的23位表示尾數的小數部分,前面加上整數部分的1,再左移23位之後就是101000011101000011110110B=10604790。那麼原值就是10604790右移23位,再左移-10位,即10604790右移33位。而233=8589934592。所以原值就是10604790/8589934592=0.0012345600407571,可見前10位小數都是正確的,精度還可以

最後試個double的123.456

電腦里存儲的是兩個32位數:1079958831(高)、446676599(低)

二進位就是:01000000010111101101110100101111,00011010100111111011111001110111B。其中第一個0表示正值;指數位是10000000101B=1029,表示指數為(1029-1023)=6;最後是52位尾數,前面加上整數部分的1,再左移52位之後,11110110111010010111100011010100111111011111001110111B=8687443681197687。因此,原值就是8687443681197687右移52位,再左移6位,即右移46位,而246=70368744177664。
8687443681197687/70368744177664=123.456

好吧,double的精度確實高,比float表示的准多了!
我是泰山,專註VX 15年!
一起學習,共同進步!