浮点数存储格式学习:找到非规格数中最大和最小的数

在学习《深入理解计算机系统》的浮点数存储里,我想到一个问题,单精度浮点数中,非规格浮点数最大数是几?

00000000011111111111111111111111

符号位:0

指数域:00000000

小数域:11111111111111111111111

指数域全0,小数域全1,符号位0,这个数应该是非规格数中最大的一个了,那么这个数存在吗?计算机是这样存储的吗?

单精度浮点数:符号位1个,指数位8个,小数位23个,偏置值bias=127,E=1-bias=-126,M=f=(0.11111111111111111111111)2

根据存储定义:浮点数V=(-1)sM2E,V=(0.11111111111111111111111)2 * 2-126

让我们开始编程查看一下吧:

#include <cstdio>
int main(){
    float a=0.5,c=0.5;
//第一个for是将a的值累加到(0.111...11),注意0.5在二进制下就是0.1
for(int i=0;i<22;i++){ c*=0.5; a=a+c; }
//第二个for将a和2-126相乘。
for(int i=0;i<126;i++){ a*=0.5; } unsigned int b=*(int *)&a; for(int i=0;i<32;i++){ printf("%d",(b>>(31-i))&1?1:0); } printf(" b=%d ",b); return 0; }

输出:

vagrant@ubuntu-bionic:~$ ./t
00000000011111111111111111111111
b=8388607     //震惊,连b的值都有意义了,8388607=223-1

解释:第一个for中,将循环次数设为22,是因为a本身有一个1,只需再加22个就够了。更有意思的是:如果把次数改为23,则全0,也就是浮点数的0了,如果改为24,那么就是规格数中最小的一个喽,呵呵,有意思,终于理解《深解》说的平滑过渡啥意思了。

那么这个最大的非规格浮点数到底是多少呢?在上面程序加上一句:

printf("%.200f
",a);

输出:

vagrant@ubuntu-bionic:~$ ./t
00000000011111111111111111111111
a=0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875000000000000000000000000000000000000000000000000000

最后面的0可以删除,这样是为了看着方面,确认没数了。这个数最大的非规格浮点数是:

a=0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875

数字前面有37个0,a*1038约等于1.1755,这还是非规格数里面最大的一个,晕。

那么最小的非规格数是多少呢?基本和前面同理:

#include <cstdio>
int main(){
    float a=0.5;
    for(int i=0;i<22;i++){
        a*=0.5;
    }
    for(int i=0;i<126;i++){
        a*=0.5;
    }
    unsigned int b=*(int *)&a;
    for(int i=0;i<32;i++){
        printf("%d",(b>>(31-i))&1?1:0);
    }
    printf("
a=%.200f
",a);
    printf("
b=%d
",b);
    return 0;
}

输出:

vagrant@ubuntu-bionic:~$ ./t1
00000000000000000000000000000001
a=0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125000000000000000000000000000000000000000000000000000

b=1

这就是浮点数,如果你懂它,它也很精确的。

原文地址:https://www.cnblogs.com/litifeng/p/10488908.html