C/C++的浮點數據類型有float和double兩種。
類型float大小為4字節,即32位,內存中的存儲方式如下:
符號位(1 bit) 指數(8 bit) 尾數(23 bit)
類型double大小為8字節,即64位,內存布局如下:
符號位(1 bit) 指數(11 bit) 尾數(52 bit)
符號位決定浮點數的正負,0正1負。
指數和尾數均從浮點數的二進制科學計數形式中獲取。
如,十進制浮點數2.5的二進制形式為10.1,轉換為科學計數法形式為(1.01)*(10^1),由此可知指數為1,尾數(即科學計數法的小數部分)為01。
根據浮點數的存儲標準(IEEE制定),float類型指數的起始數為127(二進制0111 1111),double類型指數的起始數為1023(二進制011 1111 1111),在此基礎上加指數,得到的就是內存中指數的表示形式。尾數則直接填入,如果空間多余則以0補齊,如果空間不夠則0舍1入。所以float和double類型分別表示的2.5如下(二進制):
符號位 指數 尾數
0 1000 0000 010 0000 0000 0000 0000 0000
0 100 0000 0000 0100 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000
浮點數2.5可以用二進制小數準確表示(2.5=1*(2^1)+0*(2^0)+1*(2^-1)),但很多小數不可以準確表示,其二進制形式的小數部分會無限循環,如浮點數-1.2表示如下(二進制):
符號位 指數 尾數
1 0111 1111 0011 0011 0011 0011 0011 010
1 011 1111 1111 0011 0011 0011 0011 0011 0011 0011
0011 0011 0011 0011 0011 0011
由于對無限循環尾數的截取遵循0舍1入,尾數的第21~24位為0011,第53~56位為0011,而float尾數容量為23位,double尾數容量為52位,所以,float形式的最后三位因進位而成010,double形式則沒有進位發生。
類型float和double通過==,>,<等比較不會引起編譯錯誤,但是非??赡艿玫藉e誤的結果。這是因為它們的內存分布不同,不可以直接比較。正確的方法是轉換為同一類型后比較兩者差值,如果結果小于規定的小值,則視為相等。
如,一個比較double的實現:
http://metasharp.net/index.php?title=How_to_compare_double_or_float_in_Cpp
另外,本文參考了如下webs:
http://cdatatype.blogspot.com/2008/01/memory-map-of-floatdouble.html
http://blog.csdn.net/hzb1983/archive/2007/09/24/1798555.aspx
P.S.
1)
IEEE浮點數標準: 4字節浮點數:1位符號位,8位階數(基數為127的移碼),23位尾數; 8字節浮點數:1位符號位,11位階數(基數為1023的移碼),52位尾數
2 )
在VC中: float數值范圍約在 -10e38~10e38,并提供7位有效數字位,絕對值小于10e38地數被處理成零值 double數值范圍約在-10e308~10e308,并提供15~16位有效數字,絕對值小于10e308地數被處理成零值
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/vinsendai/archive/2008/06/27/2593035.aspx