• 【C语言】浮点数在内存中的存储


    浮点数表示的范围在头文件float.h中定义。

    1. 浮点数的存储规则

    根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成这种形式:

    (-1)^S * M * 2^E

    1. (-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
    2. M表示有效数字,1≤M<2。
    3. 2^E表示指数位。

    十进制的5.5,写成二进制是101.1 ,相当于1.011×2^2 。此时,S=0,M=1.011,E=2。

    1. 对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。
    2. 对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
    单精度浮点数存储模型
                                    
    SE(8位)M(23位)
    双精度浮点数存储模型
                                    
    SE(11位)M
                                    
    (52位)

    2. 对于M的规定

    1≤M<2 ,即M可以写成1.xxxxxx的形式。IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。

    3. 对于E的规定

    E为一个无符号整数(unsigned int),如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数127;对于11位的E,这个中间数是1023。 

    例如,十进制的5.5(float),写成二进制是101.1 ,相当于1.011×2^2 。此时,S=0,M=1.011,E=2。M只保存011,E存储2+127=129,即10000001,所以5.5(float)的存储形式为:01000000101100000000000000000000

    指数E从内存中取出分为三种情况:

    3.1 E不全为0或不全为1

    E:减去中间值(127或1023)

    M:前面加上1.

    例如,01000000101100000000000000000000,S=0,M=1.011,E=2,为1.011×2^2,即101.1,十进制为5.5。

    3.2 E全为0

    E:1-中间值(=-126或-1022)

    M:前面加上0.

    例如,00000000001100000000000000000000,S=0,M=0.011,E=-126,为0.011×2^(-126),表示一个接近于0的很小的数字。

    3.3 E全为1

    E:255-127=128或2047-1023=1024

    M:如果M全为0,表示±∞

    例如,01111111100000000000000000000000表示正无穷大。

    4. 练习题

    1. #include
    2. int main()
    3. {
    4. int n = 9;
    5. float* pFloat = (float*)&n;
    6. printf("n的值为:%d\n", n);//9
    7. printf("*pFloat的值为:%f\n", *pFloat);//0.000000
    8. *pFloat = 9.0;
    9. printf("num的值为:%d\n", n);//1091567616
    10. printf("*pFloat的值为:%f\n", *pFloat);//9.000000
    11. return 0;
    12. }
    1. int n = 9;
    2. float* pFloat = (float*)&n;

    9的补码:00000000000000000000000000001001

    n:9

    *pFloat:00000000000000000000000000001001,为0.00000000000000000001001×2^(-126),当有效数字为6位时,输出0.000000

    1. int n = 9;
    2. float* pFloat = (float*)&n;
    3. *pFloat = 9.0;

    *pFloat:9.0表示成二进制为1001.0,即1.001×2^3,存储为01000001000100000000000000000000,当有效数字为6位时,输出9.000000。

    num:01000001000100000000000000000000----输出整型---->1091567616

  • 相关阅读:
    asp.net+sqlserver汽车4s店销售网站系统c#项目
    基于SSM的医院医疗管理系统的设计与实现
    纸牌博弈问题
    Kafka 认证一:PlainLoginModule 认证及 Java 连接测试
    三十四、数学知识——约数(试除法 + 约数个数 + 约数之和 + 欧几里得算法)
    防火墙实验一
    工作失误合集,这个月的工资被扣没咯!
    计算机网络性能指标
    容器化 | 在 Kubernetes 上部署 RadonDB MySQL 集群
    k8s 读书笔记 - 详解 Pod 调度(Ⅱ卷)
  • 原文地址:https://blog.csdn.net/Qiuhan_909/article/details/125778071