思维导图:
浮点型在内存中的存储
1.1一个经典的例子
#include 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; }
通过观察我们可以发现,用整形的方式存储和用浮点型的形式存储,拿出来的结果不同。
由此,我们可以大胆推测,整形和浮点型在内存中的存储方式不同。
那浮点型在内存中究竟是怎么存储的呢?
1.2 浮点数存储规则
根据国际标准IEEE(电气和电子工程协会) 754,
任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位
举一个简单的例子:
十进制的 5.0
先转换成二进制:101.0
写成浮点数的形式:(-1)^0 * 1.01 * 2^2
相当于:S=0 , M=1.01 , E=2
那浮点数又是怎么存到内存里面的呢?
IEEE 754规定:
对于32位的浮点数,最高的1位是符号位s,
接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,
接着的11位是指数E,剩下的52位为有效数字M。
并且,规定中还有一些特殊的规则:
E是一个无符号整数,
这意味着当E为8位时,取值在1~255,
当E为11位时,取值在0~2047,
但是在实例中,E有可能为负数,所以,
IEEE 754规定,存入内存时E的真实值必须再加上一个中间数
单精度时加127,双精度时加1023
当然,规则总是说不完的,我们直接上实例:
1.3实践举例
我们通过刚刚学的存储方式,直接对一开始的那段代码进行分析:
#include int main() { int n = 9;//以整形的形式存储 //补码 - 00000000000000000000000000001001 //转换形式 //用浮点型的形式取出 //0 00000000 00000000000000000001001 //(-1)^0 * 0.00000000000000000001001 * 2^-126 //0.000000 float* pFloat = (float*)&n;//强制类型转换成浮点数的指针 printf("n的值为:%d\n", n);//以整形的形式取出//没有变化,打印 9 printf("*pFloat的值为:%f\n", *pFloat);//以浮点数的形式取出//打印 0.000000 *pFloat = 9.0;//以浮点数的形式存储 //9.0 //二进制 - 1001.0 //(-1)^0 * 1.001 * 2^3 //s=0, e=3, m=1.001 //补码 - 01000001000100000000000000000000 printf("num的值为:%d\n", n);//以整形的形式取出//打印 1091567616 printf("*pFloat的值为:%f\n", *pFloat);//以浮点数的形式取出//打印 9.000000 return 0; }
这就是浮点型在内存中的存储。
写在最后:
以上就是本篇文章的内容了,感谢你的阅读。
如果喜欢本文的话,欢迎点赞和评论,写下你的见解。
如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。