c++中共有3種浮點型別:float、double和long double。其中float一般為32位,double為64位,long double 為64位以上。
範圍
float和double的具體區別為
float:
1bit(符號位) 8bits(指數字) 23bits(尾數字)
double:
1bit(符號位) 11bits(指數字) 52bits(尾數字)
其中指數字決定了他們的指數範圍,也就是說:
float的指數是-127~128,即可以表示的數字大小範圍是2-127 到2128
同理double為2-1023 到21024 。
在有符號的前提下,float可以表示-2128 到2128 的資料。
我們可以把任何二進位制浮點數都化成如下標準形式:
精度
結論:float可以保證十進位制科學計數法小數點後6位有效精度和第7位的部分精度
double可以保證十進位制科學計數法小數點後15位有效精度和第16位的部分精度
浮點數的精度是由尾數來決定的。實際上乙個浮點數的數值=(符號)尾數2指數 。
那麼具體的精度就要看尾數能表示多少:
float的尾數為23位,也就是能表示223 =8388608。也就是最大能表示8.3886082128
並且精度最大為8位(只能保證7位最精確)。
double的尾數是52位,2^52 = 4503599627370496,一共16位,精度保證15位精確。
以float為例:
根據二進位制轉為10進製: (+/-)1.f * 2e
但是此e非彼e----公式中的e要計算偏移。由於指數是從2-127~2128,所以實際上的e應該是儲存的偏移量e-127。
修改後為(-1)^s * 1.f * 2^(e - 127)^
因此對於單精度浮點數2.25f來說,它的二進位制為10.01=1.001*21
s=0,e=1+127=128=1000 0000,f=0010 0000 0000 0000 0000 000
即0100000000010000000000000000000
特殊情況:
其次,對於e = 0和e = 255,有特殊的意義,總結如下:
1)e = 0 & f = 0
此時表示的單精度浮點數就是0,可以是正0,也可以是負0。負0的表明表示的實際上是乙個非常小的負數,但是這個數已經無法用單精度的儲存方式來表示了,比如1.11 * 2^(-129)已經無法用單精度表示了,因為即使-129加了127的偏移量,仍然落在了e的值區間[0, 255]之外。
2) e = 0 & f != 0
此時表示的數可有下面的工時推出:
(-1)^s * 0.f * 2^(-127)
其中s仍然表示符號位,這種形式被稱為非標準形式
3) e = 255 & f = 0
此時表示正無窮或者負無窮,依據符號位決定
4)e = 255 & f != 0
此時表示nan
小數的二進位制表示問題
首先我們要搞清楚下面兩個問題:
(1) 十進位制整數如何轉化為二進位制數
演算法很簡單。舉個例子,11表示成二進位制數:
11/2
=5 餘 15/
2=2 餘 12/
2=1 餘 01/
2=0 餘 1
0結束 11二進位制表示為(從下往上)
:1011
這裡提一點:只要遇到除以後的結果為0了就結束了,大家想一想,所有的整數除以2是不是一定能夠最終得到0。
換句話說,所有的整數轉變為二進位制數的演算法會不會無限迴圈下去呢?絕對不會,整數永遠可以用二進位制精確表示 ,但小數就不一定了。
(2) 十進位制小數如何轉化為二進位制數
演算法是乘以2直到沒有了小數為止。舉個例子,0.9表示成二進位制數
0.9*2
=1.8 取整數部分 10.8
(1.8的小數部分)*2
=1.6 取整數部分 1
0.6*2=
1.2 取整數部分 1
0.2*2=
0.4 取整數部分 0
0.4*2=
0.8 取整數部分 0
0.8*2=
1.6 取整數部分 1
0.6*2=
1.2 取整數部分 0..
....
...0.9二進位制表示為(從上往下)
:1100100100100...
... 注意:上面的計算過程迴圈了,也就是說*
2永遠不可能消滅小數部分,這樣演算法將無限下去。很顯然,小數的二進位制表示有時是不可能精確的 。
其實道理很簡單,十進位制系統中能不能準確表示出1
/3呢?同樣二進位制系統也無法準確表示1
/10。這也就解釋了為什麼浮點型減法出現了"減不盡"的精度丟失問題。
浮點數學習筆記
乙個機器浮點數由階碼和尾數及其符號位組成 尾數 用定點小數表示,給出有效數字的位數,決定了浮點數的表示精度 階碼 用定點整數形式表示,指明小數點在資料中的位置,決定了浮點數的表示範圍。2 浮點數的標準格式 e.m 為便於軟體移植,使用 ieee 電氣和電子工程師協會 標準 ieee754 標準 尾數...
浮點數 儲存
關鍵字 體系結構 ieee754 浮點數 儲存 main 如果不執行上面的 讓我們來直接判斷,輸出的結果會是什麼?而在你執行程式之後,結果卻很讓人詫異 123.456001。為什麼會是123.456001?有六位小數可以理解,最後那個1是為何?有很多人解釋說最後那個1是亂碼,隨機的。嘿嘿 其實無論你...
浮點數操作
float fx 49.03f int nx fx 100 printf d nx 執行上述 結果 4902。用vc6.0,2005,gcc編譯執行結果都是一樣。為什麼會這樣呢,是因為浮點數運算具有不精確性。其實編譯上面的 編譯器會有警告的。warning c4244 initializing co...