C语言浮点型数据在内存中的存储

时间:2021-09-11 00:50:59

前言

根据国际标准IEEE(电气和电子工程协会)754规定,C语言中的任何一个浮点数V都可以写成(-1)^S * M * 2^E。

(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。M表示有效数字,大于等于1,小于2。2^E表示指数位

所以在C语言中,浮点型数据在内存中储存的是S,E,M,存储顺序也是SEM

一、float类型

1.1float类型在内存中的存储

floatl类型是4个字节,32个比特位,我们规定从左到右,第一个比特位存储S,接下来8个比特位存储E(double是11位),剩下的23个比特位存储M(double是52位)

其中S只用表示该浮点数的正负,

E是用科学计数法表示的浮点数的指数,但是我们又规定E是无符号整数,所以E不能为负数,可我们将0.5用科学计数法表示后,E的值为-1,因此我们又规定保存的是E+127(double是E+1023),127是规定的一个中间值,用来确保E为非负

M是用科学计数法表示的浮点数底数部分,因为规定的M是>=1,<2的,所以我们又规定我们不在保存整数部分的1,而是只保存其小数部分

例如 int a=5.5;

二进制为,101.1,写成IEEE 754规定形式为,(-1)^0 * 1.011 * 2^2,其中,S=0,E=2,M=1.011,但我们在存储时,存储的分别是0,129,011

其中129要写成8位的二进制序列,为10000001

而M占了23个比特位,而表示M只用了3个比特位,所以其余比特位需要在末尾补0

即011 0000000000 0000000000

所以32个比特位依次存储的是S,加了中间值127的E,以及省略了整数部分1的M,其二进制序列为,0100 0000 1011 0000 0000 0000 0000 0000

转化为16进制为40 b0 00 00,让我们来验证一下,代码如下

#include<stdio.h>

int main()

{

float a = 5.5f;

printf("%f ", a);

}

C语言浮点型数据在内存中的存储

我们可以看到在调试后,float类型的a在内存中的地址确实和所讲的一致

1.2float类型数据的取出

取出其实是存入的反过程,此时我们是要用得到的SEM的值,用科学计数法的方式表示,但在取出过程中,我们又有了新的规定,

1.当存入的E不全为0或者不全为1时,我们需要给存入的E-127(double为E-1023)得到真实的E,因为我们在存储E的时候,为了保证E非负,给E+127,有效数字M前加上1.,

2.当存入的E全为0时,此时真实的E为-127,我们可以想象一下,一个用科学计数法表示的数字的指数为-127,它是不是无限的向+-0接近,因此规定,E=1-127(或者1-1023),此时有效数字M不再加上1,而是直接还原为0.xxxxx的小数

3.当E全为1时,如果有效数字全为0,表示+-无穷大