C语音进阶————数据在内存中的存储2

2026年1月27日学习总结:

本次学习主要围绕数据在内存中的存储的浮点数的存储部分,主要分为以下三个部分:

首先在进入本次学习的内容之前先复习一下浮点数的相关知识点:

①常见浮点数:3.14159,9.18;

②浮点数家族包括:float、double、long double类型;

③浮点数表示的范围:float.h中定义;整数表示的范围在:limits.h中定义。

1.一个例子:

cs 复制代码
#include<stdio.h>
int main()
{
	int n = 9;
	float* nFloat = (float*)&n;
	printf("n的值为%d\n", n);  //9
	printf("*nFloat的值为%f\n", *nFloat);  //0.000000  
	*nFloat = 9.0;
	printf("n的值为%d\n", n);  //1091567616   修改成浮点数类型的数据,整数去访问的值则不准确
	printf("*nFlost的值为%f\n", *nFloat);  //9.000000 
	return 0;
}

运行结果:

这个例子不仅告诉我们整型和浮点数的存储方式不同,数据处理方式也不同。也告诉我们存什么值就用什么类型。

2.浮点数存储规则

n和*nFloat在内存中明明是同一个数,为什么浮点数和整数的解读结果会差这么多?要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。

详细解读:根据国际标准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.01*2^2。

小数在内存中可能无法精确保存,如V=9.6=1001.100......0000,所以会出现我们输入的数可能无法一样。

(1)IEEE 754的存储规定:

①对于32位的浮点数float,最高的1位为符号位S,接着的8位是指数E,剩下的23位为有效数字M。

②对于64位的浮点数double,最高的1位为符号位S,接着的11位是指数E,剩下的52位为有效数字M。

(2)IEEE 754对有效数字M和指数E还有一些特别规定:

①规定在计算机内部保存M时,默认这个数第一位总是1,因此可以被舍去,只保存后面的剩余部分。如:保存1.01时,只保存01,读数时才加上1。

目的:节省一位有效数字。以32位为例,留给M只有23位,但第一位舍去后就有24位有效数字。

②对于指数E就比较复杂

首先,E为一个无符号整数(unsigned int),8位时取值范围:0~255;11位时取值范围:0~2047。但是实际上E是可以出现负数的,所以规定存入内存的真实值必须加上一个中间数,8位的中间数是127,11位中间数是1023。

然后,指数E从内存中取出还可以分为三种情况:

a.E不全为0或者不全为1:指数E的计算值减去127(或者1023),得到真实值,再将数字M前加上第一位的1。

b.E全为0:浮点数的指数E等于1-127(或1-1023)即为真实值。有效数字M不再加上第一位1,而是还原为0.XXXXXX的小数,这样做是为了表示±0、以及接近于0的很小的数。

c.E全为1:如果有效数字M全为0,表示±无穷大(正负取决于符号位S)。

最后再对上面示例的值进行解释:

cs 复制代码
#include<stdio.h>
int main()
{
	int n = 9;
	//原、反、补码:00000000 00000000 00000000 10010000
	float* nFloat = (float*)&n;
	//用浮点数的存储规则去读,S=0,E=00000000,M=0000000 00000000 10010000
	//所以有效值为0.0000000 00000000 10010000
    //按照读取规则精确到小数点后6为就为0.000000
	printf("n的值为%d\n", n);  //9
	printf("*nFloat的值为%f\n", *nFloat);  //0.000000  
	*nFloat = 9.0;
	//用浮点数表示时:1.001*3
	//符号位S=0,指数E=3,有效数M=1.001
	//存储为:0 10000011 00100000000000000000000而用整数来读取就为1091567616
	printf("n的值为%d\n", n);  //1091567616   
    //修改成浮点数类型的数据,整数去访问的值则不准确
	printf("*nFlost的值为%f\n", *nFloat);  //9.000000 
	return 0;
}
相关推荐
梦里寻码22 分钟前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
FRing0324 分钟前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
旖旎夜光26 分钟前
【C++ 基础入门】C++ 多态(上):虚函数、重写、override/final 与抽象类
开发语言·c++·笔记·学习
猿人谷1 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
starzy19901 小时前
深入理解Scala嵌套函数:作用域封装之道
开发语言·scala
Sakura_j_h_1 小时前
从零写一个 MCP stdio Server:用 Python 校验博客文章格式
开发语言·python·自动化·ai工具·mcp·json-rpc
青少儿编程课堂2 小时前
蓝桥杯青少组图形化 STEMA 省考(报名倒计时·11/22开考)+ 全国青少年信息素养大赛 2026—2027赛季 + 电子学会图形化考级:校园华容道大闯关
c++·python·算法·bfs·信息学竞赛
白杨尚青3 小时前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
.道阻且长.3 小时前
Linux基本开发工具:gdb和cgdb的使用
linux·运维·服务器·开发语言