浮点型数据在内存中的储存
文章目录
- 浮点型数据在内存中的储存
- 引例
- 概念提出
- 浮点型数据储存规定
- 对于有效数字M的特别规定
- 对于指数E的特别规定
- 指数E的储存
- 指数E的读取
- 利用规则解释原因
在之前学习过整形数据在内存中的储存后,浮点型数据在内存中的储存又会怎样呢?
常见的浮点型包括,float,double,long double类型
引例
#include<stdio.h>
int main()
{
int n = 9;
float* f = (float*)&n;
printf("n的值为%d\n", n);
printf("*f的值为%f\n", *f);
*f = 9.0;
printf("num的值%d\n", n);
printf("*f的值为%f\n", *f);
return 0;
}
通过结果不难发现,*f和num在内存中明明是同一个数,但是浮点型和整形数据的输出结果天差地别,出现这个结果的原因就是,浮点数在计算机内部的存储方式有自己的规则
概念提出
根据国际标准IEEE(电气电子工程师学会)754,任意一个二进制浮点数V 可以表示成下面的格式
1.(-1)^S* M * 2^E
2.(-1)^S表示符号位,当S=0时,V为正数,当S=1时,V为负数
3.M表示有效数字,大于1,小于2
4.2^ E表示指数位
举例来说,十进制的5.5,写成2进制就是101.1(这里的小数位上的1是因为2^(-1)=0.5),相当于是1.011* 2^2,由此可以得出s=0;M=1.011,E=2;
十进制的-5.0写成二进制是-101.0,相当于-1.01*2^2,那么,S=1;M=1.01,E=2;
浮点型数据储存规定
IEEE 754规定
对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M
对于64位的浮点数,最高的一位是符号位S,接着是11位的指数E,剩下的52位为有效数字M
对于有效数字M的特别规定
在概念提出部分就有提到,1<=M<2,意思就是M一定是会被写成1.XXXXXXX,那么就可以省略掉1,只保存后面的XXXXXXXX部分
比如说上面的1.01,就只保存01,到读取的时候,再把第一位的1加上去,这样做的目的,就是可以节省一个有效数字的位置
毕竟有效数字的位置是有限的,多省出一个,就更能增加数据的精度
对于指数E的特别规定
指数E的储存
***首先,E是一个无符号整数,(unsigned int),那么如果E为8位,他的取值范围在0~255,如果E为11位,它的取值范围在0 ~2047。但是,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时,E的真实值必须加上一个中间数,对于8位的E,中间数时127,对于11位的E,中间数时1023,比如,2^10的E是10,所以保存为32位浮点数时,会被保存成10+127=137;即10001001。
指数E的读取
E不全为0或不全为1
这时,浮点数的读取规则如下:
指数E的计算值间区127(或1023),得到真实值,再将有效数字M前加上第一位的1,比如0.5的二进制是0.1,——>1.0* 2(-1),其阶码位-1+127=126;表示为01111110.
对于M,尾数1.0的小数部分为0,所以补0补齐23位
0 01111110 00000000000000000000000
E全为0
这时,浮点是指数E等于1-127(1-1023),即为真实值,有效数字M前边不在加1,而是还原为0.XXXXXXXX的小数,这样来表示正负0,或者接近0的很小的数
E全为1
这时,如果有效数字M全为0,表示无穷大(正负取决于S的值)
利用规则解释原因
对于第一部分的*f
n=9;
9>00000000 00000000 00000000 00001001
将他拆分一下,
得到第一位s=0;,后面的8位指数E=00000000,最后的23位是有效数字M
0 00000000 00000000000000000001001
这里指数E为全0.E=1-127=-126,浮点数V写成
(-1)^0 * 0.00000000000000000001001 * 2^(-126)
显然V是一个很小的接近0的正数,所以用十进制小数表示就是0.000000
对于第二部分
浮点数9.0,存入内存先把他转换成二进制
1001.0,–>(-1) ^0 *1.001 *2^(3)—>s=0;E=3+127=130;M=1.001,
因为尾数1.001的小数部分是001,有效数字M后补0至23位
所以9.0在内存中储存,他的二进制为
0 10000010 00100000000000000000000
这个数还原成十进制数就是一个很大的正数,是1091567616
在按照浮点数从内存读取的规则,用小数表示就是9.000000
需要注意的是:
有很多时候小数部分我们无法非常精确的将他按照浮点型数据的规则精确储存他,例如3.14,小数部分0.14就不容易找到精确的E,并且E只有8个bit位,当计算出来的E的值的二进制位超出8个时,有一部分就会被省略
因此浮点型数据在内存中的储存往往都不是非常精确的
作者有话说:作者只是一个小白,以上仅仅是作者对知识的理解,如有错误或不足,感谢指出,如感到有帮助,请留下一个👍