參考:spa
http://jimmygod.blog.163.com/blog/static/43511339200792605627411/.net
http://blog.csdn.net/archersaber39/article/details/51422602blog
-------------------------------------------------------------------------------ci
我兩年前就知道不該該用==號來判斷浮點數的相等了,由於存在一個精度的問題,可是一直以來,都沒怎麼在意這些東西,而實際上,我對於浮點數的結構,雖然瞭解,但並不清晰. 做爲一個C++愛好者,應該儘可能搞清楚每個問題,因此我搞清楚了浮點數的內在表示及實現.在沒有大問題的狀況下,一切以易於理解和記憶爲標準.get
首先說一下原,反,補,移碼. 移碼其實就等於補碼,只是符號相反. 對於正數而言,原,反,補碼都同樣, 對負數而言,反碼除符號位外,在原碼的基礎上按位取反,補碼則在反碼的基礎之上,在其最低位上加1,要求移碼時,仍然是先求補碼,再改符號.編譯器
浮點數分爲float和double,分別佔4,8個字節,即32,64位. 我僅以32位的float爲例,並附帶說double.編譯
在IEEE754標準中,規定,float的32位這樣分:table
符號位(S)基礎 1循環 |
階碼(E) 8 |
尾數(M) 23 |
這裏應該注意三點: A,階碼是用移碼錶示的,這裏會有一個127的偏移量,它的127至關於0,小於127時爲負,大於127時爲正,好比:10000001表示指數爲129-127=2,表示真值爲2^2,而01111110則表示2^(-1).
B, 尾數全都是小數點後面的數,
C, 但尾數中省略了一個1,所以尾數全爲0時,也是1.0...00;
接下來只要說明幾個問題就明白了,以123.456爲例,表示爲二進制就是:N (2) = 1111011. 01110100101111001 ,這裏,會右移6位,獲得N (2) = 1.111011 01110100101111001*2^6; 這種形式就能夠用於上圖中的表示格式了.
符號位(S) 0 |
階碼(E) 00000110 |
尾數(M) 11101101110100101111001 |
注意到,上面的階碼第一位爲0表正,尾數比N(2)表示的第一位少了個1,這就是上面說的默認爲第一位爲1. 因爲在將十進制轉爲二進制的過程當中,經常不能正好轉得相等, (固然,像4.0這樣的就不會有損失,而1.0/3.0這樣的必然損失),因此就產生了浮點數的精度問題, 實際上,小數點後的23位二進制數,能影響的十進制數的前8位,這是爲何呢?通常人在這時每每迷迷胡胡了,其實很簡單,在上面表示的尾數中,是二進制的,小數點後有23位,最後一位的值爲1時,它就是1/2^22=0.000000238實際取的時候確定是0.0000002,也就是說,對於一個float型的浮點數,其有效的位數是從左到右數7位(包括缺省的1纔是7位),當到達上面這個第8位時,就不可靠了,但咱們的VC6能夠輸出最長的1.0/3.0爲0.33333333333333331,這主要是編譯器的問題了, 而並非說浮點數小數點後的16位都有效. 若是不信的話,能夠去試一下double類型的1.0/3.0, 獲得的也將是小數點後17位.
--------------------------------------
將20.163轉換成754標準的32位浮點數
1.將十進制數轉換成二進制數
十進制浮點數,整數部分轉換成二進制,採用除2取餘法,將餘數從低到高排列,即爲整數的二進制數;
小數部分轉換成二進制,採用乘2取整法,將取整數順序排列,即爲小數的二進制數。
小數部分乘2直到小數部分爲0,或取到想要的位數,或循環出現前。
整數部分
20/2=10 .... 0
10/2=5 .... 0
5/2=2 .... 1
2/2=1 .... 0
1/2=0 ..... 1
小數部分
0.163*2=0.326 0
0.326*2=0.652 0
0.652*2=1.304 1
0.304*2=0.608 0
0.608*2=1.216 1
0.216*2=0.432 0
0.432*2=0.864 0
0.864*2=1.728 1
0.728*2=1.456 1
0.456*2=0.912 0
不要求精度時,一般取到8~10位
20.163=10100.0010100110
2.移動小數點到第一、2位之間,得e的值
10100.0010100110=1.01000010100110 *2的4次方 e=4(小數點移動4位)
3.求出S、E、M的值
S=0,E=4+127=131,M=01000010100110
S由小數點的後一位能夠看出,0爲正數,1爲負數。
0 1000001 01000010100110000000000
IEEE754標準中32位浮點數表示
S E M
S是符號位佔1位,E是階碼佔8位,M是尾數佔23位。
當尾數的值不爲0時,尾數的最高有效位應爲1,這稱爲浮點數的規格化表示
這樣形式的叫規格化
新手初學,有問題或者錯誤,麻煩評論下 留言指正,謝謝