IEEE 754標準中,浮點數的表示方法如下:
V=(-1)s×M×2E
其中:
1、s是符號位,佔1個字元。s為1表示負數,s為0表示正數;
2、M是二進位小數,32位單精確度float中M佔23位,形式如同fn-1fn-2。。。f1f0(n=23);
3、E是指數位,32位單精確度float中E佔8位,形式如同ek-1。。。e1e0(k=8);
總體上,浮點數編碼分作三類:
1、規格化值。指數位不全為0或不全為1的情況,定義指數的值E=e-Bias,其中e為ek-1。。。e1e0表示的不帶正負號的整數,Bias定義為一個位移值,它等於2k-1-1。這樣指數的取值範圍就確定了,對32位單精確度float來說,Bias=2^7-1=127,e的最小值為[0000 0001],最大值為[1111 1110],因此指數的取值範圍為-126~127。
小數域f,其中 0<=f<1,值為0.fn-1fn-2。。。f1f0,定義M=1+f。
2、非規格化值。當指數位全部是0時,為非規格化值。這種情況下定義E=1-Bias,M=f。
3、特殊數值。當指數位全部是1、小數位全部是0時,定義s=0時,V=+∞,s=1時,V=−∞。
當指數位全部是1,小數位不全為0時,定義V=Nan(not a number)。
這時可以對照書上的圖2.23計算一下8位浮點格式下的資料。
一些重要的32位單精確度浮點數就可以計算出來(以正數為例):
1、0。指數位和小數位都為0;
2、最小非規格化數。E=1-Bias=1-127=-126,M=f的最小值為[00...01],所以V=M×2E=2-23×2-126
3、最大非規格化數。E=-126,M=f的最大值為[11...11],所以V=M×2E=(1-2-23)×2-126
4、最小規劃化數。E=e-Bias,最小e為[00...01],所以E=-126,f的最小值為[00...00],M=1+f=1.所以V=1×2-126
5、1。指數為[01..11],e=127,E=e-Bias=0,;f=[00..00],M=1+f=1,V=1*2^0=1
6、最大規格化數。指數為[11...10],E=e-Bias=127;f=[11...11],M=1+f=2-2-23,V=(2-2-23)×2127
再看一下練習題2.35,假定一個k位指數和n位小數的浮點格式,給出不能正確用浮點數描述的最小正整數的公式。
有提示了,小數位只有n為,所以一旦那個最小正整數用浮點格式表示的時候需要n+1位小數位來描述的話,就滿足題目求解的要求。當整數當轉化為二進位小數時,例如
12345=1.10000001110012×213採取的方法是拋去第一個1(之後M需要在f的值上加1來彌補這個1),剩下的部分補零至n為小數。因此實際上不能正確用浮點格式來描述的正整數應該是形如[100...01](其中有n個0)的格式,即2n+1+1
補充一個程式作為示範
#include<stdio.h>int main(void){ char c=97; short s=97; int n=97; float f=97; double d=97; int i,j; printf("char 97在電腦中的二進位表示:"); for(i=sizeof(char)*8-1;i>=0;i--) printf("%d",(c>>i)&1); //高位在前,低位在後,因此將高位的先進行移位,然後與操作,輸出時,先輸高位元據 printf("\nshort 97在電腦中的二進位表示:"); for(i=sizeof(short)*8-1;i>=0;i--) printf("%d",(s>>i)&1); printf("\nint 97在電腦中的二進位表示:"); for(i=sizeof(int)*8-1;i>=0;i--) printf("%d",(n>>i)&1); printf("\nfloat 97在電腦中的二進位表示:"); char* ip=(char*)&f; for(i=3;i>=0;i--){ for(j=7;j>=0;j--) printf("%d",(*(ip+i)>>j)&1); } printf("\ndouble 97在電腦中的二進位表示:"); ip=(char*)&d; for(i=7;i>=0;i--){ for(j=7;j>=0;j--) printf("%d",(*(ip+i)>>j)&1); } printf("\n"); return 0;}