人類世界的小數的表示形式
1、我們最習慣的小數表示形式是十進制,形式為:
它的值為:
2、小數的二進制表示法,形式為:
它的值為:
IEEE浮點標准
在計算機系統中,因為有字節的限制(C語言中float類型占4字節,double類型占8字節),小數的表示要復雜的多。IEEE制定的浮點標准得到了所有的計算機的支持。
IEEE浮點標准用如下形式表示一個數:

符號(sign)s,1為負數,0為正數。數值0的符號位解釋做特殊情況處理;
尾數(significand 有效數)M是一個小數,范圍為1~2-ε 或 0~1-ε (即 [1,2) 或 [0,1) ,詳情請看“浮點數的類型”部分)
階碼(exponent 指數)E的作用是對浮點數加權,這個權重是2的E次冪(可能是負數)
標准浮點格式(浮點有3個字段組成)有以下兩個類型:
32位的單精度:s、exp和frac字段分別為1位、8位、23位
64位的雙精度:s、exp和frac字段分別為1位、11位、52位
IEEE浮點數的類型
依據階碼字段是否全為0、全為1分為以下三種:
1、規格化的值:exp字段(階碼字段)的位模式不全為0,或不全為1.
階碼
E=e-Bias 其中,e是exp字段表示的無符號數,Bias是偏置值2^(k-1)-1(單精度為127,雙精度為1023)。階碼E以此方式來表示成有符號數。因此得到E的范圍:單精度-126~127,雙精度-1022~1023
若字段frac(尾數域)為
則定義尾數
M=1+f,其中f=
。即尾數域僅僅表示小數點后面的部分,隱含小數點前面為1。




2、非規格化的值:當階碼字段全為0
階碼
E=1-Bias
尾數
M=f,不包含隱含的開頭1
目的是表示數值0;表示非常接近與0.0的數
3、特殊值:階碼字段全為1
當尾數域全為0,表示無窮大或無窮小
當尾數域不全為0,結果值被稱為NaN(Not a Number)
我們用正數范圍內的示例,來說明上面的三種類型的重大意義
e:假定階碼字段是一個無符號整數表示的值
E:偏置之后的
階碼值
2^E:階碼的權重數
f:尾碼字段描述的小數值
M:
尾數值
V:
小數值 V=2^E * M
IEEE浮點表示的特點
1,最大非規格化數7/512 到 最小規格化數8/512的平滑轉變;
2,若將上圖中浮點數的位表達式解釋為無符號整數,它們就是按升序排列的,就像它們表示的浮點數一樣。(IEEE如此設計格式就是為了浮點數能夠使用整數排序函數來進行排序)
例如:
typedef unsigned char *type_pointer; void show_types(type_pointer start,int len) { int i; for(i=0; i<len; i++) printf(" %.2x",start[i]); printf("\n"); } int main() { float f1=1.0; show_types(&f1,sizeof(f1)); return 0; }
輸出:00 00 80 3f
分析:這個程序運行在windows 32位機上。window系統是小端法(數值的低字節放在內存的前端)機器。
對於的二進制表示為:00111111 10000000 00000000 00000000
float的第1位為符號位:0;第2至第9位為階碼位,供8位:E=127-127=0;后面的23位為尾碼,M=1+0=1。
所以,(-1)0*1*20=1.0
浮點數的舍入方式
IEEE浮點格式定義來四種不同的舍入方式。默認的舍入方式是:偶數舍入。
偶數舍入(round-to-even):找最接近的數值,舍入到這個值;如果有兩個可能的值,將數字向上或向下舍入,使得到的結果的最低有效數字是偶數。
例如,將下面二進制舍入到小數后一位:
11.001(2)->舍入:11.0(2) 11.0是最接近的數值
10.010(2)->舍入:10.0(2) 10.0 和 10.1都是最接近的值,但是10.0的最低位為偶數
10.110(2) ->舍入:11.0(2) 10.1 和 11.0 都是最接近的值,但是11.0的最低位為偶數
浮點運算
我們將
x +
f y定義為Round(x + y)
,這是對實際運算的精確結果進行舍入后的結果。


浮點加法的特點:
1、浮點加法不具有結合性。(由於可能發生溢出,或者舍入而失去精度)
float f1=(3.14+10000000000)-10000000000; float f2=3.14+(10000000000-10000000000); printf("%f %f ",f1,f2);
輸出:3.139999 3.140000
2、浮點加法滿足了單調性。
無符號和補碼加法不具有這個實數加法的屬性(因為溢出的原因)
必須非常小心地使用浮點運算,因為浮點運算只有有限的范圍和精度,而且不遵守普遍的算術屬性,比如結合性。
不能表示 VS 不能精確表示
在浮點數的表示范圍內,有多於 99.999…% 的數在計算機中是不能表示的。從數量級分析一下,32bit 浮點數的表示范圍是 10 的 38 次
方,而表示個數呢,是 10 的 10 次方。 能夠被表示的數只有 1/100000000…. (大概有30個零)。詳細內容請見“代碼之謎(五)- 浮點數(誰偷了你的精度?)”
(轉載請注明出處 ^.^)