c语言中浮点数的表示

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


 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值