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;
}