我们已经介绍过整数在内存中的存储方式,那浮点数在内存中是怎样存储的呢?
先看一段代码:
#include<stdio.h>
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n 的值为: %d\n", n);
printf("*pFloat 的值为:%f\n", *pFloat);
*pFloat = 9.0;
printf("num值为: %d\n", n);
printf("*pFloat值为: %f\n", *pFloat);
return 0;
}
是不是会觉得是
9
9.0
9
9.0
运行之后:
发现我们的猜想是不对的,那为什么会是这样的结果呢,先搜索一下浮点数在内存中的内存规则:
存储一个浮点数也是占用了32字节。并且把这32字节分为了3部分。用5.5这个浮点数举例子:
S:
如果浮点数为正则为0,负则为1 (-1)^s
那S的位置就是 0
E:
我们都知道在内存中用0和1来存储。
在浮点数存储规则中,那实际上5.5可以分为小数点前的5.0和小数点后的0.5
5.0可以表示为:101
0.5是2的-1次方
那5.5就是1.011*2^2就是1.011 乘以 2的2次方
如果写成这样科学计数法的方式,小数点前的1就不需要存储了,因为任何数用科学计数法表示肯定都是1.xxx乘以2的几次方的形式
为了使表达的数字更精确,这里的E用的是unsigned int的数表示的。用8位来存储
那本来8个字节可以表示的范围是-128~127
这样一来,就可以表示0~255
那如果是负数就+127
就像这里保存2实际上保存的是2+127=129
即:10000001
那E的位置就是 10000001
M:
M保存的就是剩下的011了
那剩下的23位,我们规定从左到右使用
那M的位置就是:01100000000000000000000
合起来就是:01000000101100000000000000000000
那再来看刚开始的代码:
n=9在内存中存储为:00000000 00000000 00000000 00001001
那S读出来是0 E读出来是0 M读出来是一个很小很小的数
转换完就是(-1)^0 * 1001 * 2^(-127)
这是一个很小很小的数,所以会打印出0.0000000000
那用浮点数规则存储9.0
S保存的就是:0
9.0就是1001.0,就是1.001*2^3
E保存的就是130 即:10000010
M保存的就是00100000000000000000000
合起来就是:01000001000100000000000000000000
用计算器计算得到:
与上面计算的结果相同。
总体上来说:
S:表示浮点数的正负
E:代表是2的几次方。
M:存储小数点后面的数字
S占1字节,E占8字节,M占23字节