【C语言进阶深度学习记录】三 浮点数(float) 在内存中的表示方法
- 相信大多數人知道整形數在內存中的分布方式,而且也能很容易寫出其二進制的形式,但是對于浮點數,估計知道的人并不是很多
- 今天學習在C語言中浮點數在內存中的表示方法
文章目錄
- 1 浮點數在內存中的存儲方式
- 1.1 浮點數的轉換步驟
- 1.2 浮點數的轉換實際例子分析
- 1.3 編程驗證測試
- 2 int與float類型的范圍的比較
- 2.1 float數不精確的編碼案例
- 3 總結
1 浮點數在內存中的存儲方式
- 浮點數在內存中的存儲方式為:符號位+指數+尾數。對于float與double類型的存儲方式,如下圖所示:
- float與double類型的數據在計算機內部的表示法是相同的,但是由于所占存儲空間的不同,其分別能表示的數值范圍和精度不同。
上面的表示法,可能并不是很好理解,看到后面的例子就會恍然大悟。
1.1 浮點數的轉換步驟
具體如何將浮點數轉換成內存中的二進制(或者十六進制的形式),下面就來看看轉換步驟。
- 注意,第三點需要明白,計算指數時需要加上偏移量(這里不講解為什么存在偏移量,后序文章會學習),對于float與double類型,加上的偏移量是不一樣的。具體如下:
對于指數為6,偏移后的值為:
float:6+127 ---->> 133
double : 6+1023 ---->> 1029
對于上面的內容,目前可能還沒有理清。但是下面的例子,可以將上面的所有內容學習明白
1.2 浮點數的轉換實際例子分析
上面說了一堆,這里來一個例子徹底明白上述的轉換規則。
- 實數8.25在內存中的float表示為如下:
首先是確定8.25的二進制表示形式:1000.01
然后用科學技術法表示二進制浮點數:1.00001 * (23).
計算符號位:3+127 = 130 ----> 10000010
符號位為0, 10000010 , 小數為(尾數):00001
由上面4條的計算以及前面的規則,得到8.25的float表示為:
- 0 10000010 00001000000000000000000 ----> 0x41040000
至此,已經得出了8.25的浮點數表示形式。對于double的表示形式,可以自己進行推導。
1.3 編程驗證測試
對于1.2小節的內容,可以編寫下面的程序來進行驗證:
#include <stdio.h>int main() {float f = 8.25;unsigned int* p = (unsigned int*)&f;printf("0x%08X\n", *p);return 0; }運行結果也是等于: 0x41040000 可以驗證上述規則與推導的正確性。
2 int與float類型的范圍的比較
我們知道int與float都是占用4字節內存,但是他們所能夠表示的數的范圍并不是一樣的。如下圖:
- int 類型的范圍:[-231 , 231]
- float類型的范圍:[-3.4 * 1038 , 3.4 * 1038]
首先拋開float為什么是這個范圍不說(具體的原因本文不講)。為什么int和float同樣是占用4字節的內存,但是float所表示的數的范圍明顯比int的范圍大很多?
其實只要占用的字節數相同,那么所能表示的數的個數,就一定相等,比如一字節的內存就最多能表示 256個數字。但是有符號和無符號表示的數范圍就不一樣。注意,是數范圍不一樣,但是他們都只能表示256個數字。只是這256個數字的范圍不在同一個區間。
那么float也是一樣,它也是只能表示與int類型一樣多的數字,只是float表示的數的范圍是上面的那樣而已。它能表示的數的范圍很大,不要被這一點迷惑。
- 可能我們覺得[-3.4 * 1038 , 3.4 * 1038] 這個區間很大,它的個數比int表示的個數多很多。 注意,這個想法是錯誤的!!!
- float所表示的數不是連續的數,在[-3.4 * 1038 , 3.4 * 1038]這個區間,存在很多空洞,只有少部分是表示float的數。
- float只是一種近似的表示法,不能作為精確數使用。
當然這一切,都是由于float的內存表示法的不同造成的。有興趣的人可以研究一下,上述float的數的范圍區間是如何來的。
2.1 float數不精確的編碼案例
看下面的代碼:
#include <stdio.h>int main() {float f = 3.1415f;float fl = 123456789;printf("%0.10f\n", f);printf("%0.10f\n", fl);return 0; }編譯運行結果為:
3.1414999962 123456792.0000000000這個結果貌似與我們所期盼的結果有很大的出入。但是 這就是正常的結果,因為float表示的數是不精確的,像上面的數3.1415f ,float就無法表示這樣的數,雖然它在區間[-3.4 * 1038 , 3.4 * 1038]中,但是float就是無法精確表示它,只能打印它最接近這個數的一個數。所以打印結果是另一個數。
- 這也驗證了上面關于說float無法精確表示一個數的說法
3 總結
- 浮點數與整形數的內存表示法不同
- 浮點數類型可表示的范圍更大
- 浮點類型是一種不精確的類型
- 由于浮點數的內存表示法比較復雜,所以浮點數的運算速度很慢
- float所表示的數不是連續的數
總結
以上是生活随笔為你收集整理的【C语言进阶深度学习记录】三 浮点数(float) 在内存中的表示方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安装oracle-java,并覆盖原先的
- 下一篇: 梳理百年深度学习发展史-七月在线机器学习