椋鸟C语言笔记#26:数据在内存中的存储(大小端字节序)、浮点数的存储(IEEE754)

IEEE-754单精度浮点类型存储(每个步骤都有画图,清晰明了,通俗易懂) 本文介绍了IEEE-754标准单精度浮点类型在计算机内存中的存储规则,每一步都有图片,详细介绍了单精度浮点类型如何转换为二进制存储计算机内存的过程。 阅读详情

萌新的学习笔记,写错了恳请斧正。


目录

大小端字节序

什么是大小端

写一个判断大小端的程序

浮点数在内存中的存储(IEEE 754规则)

引入

存储规则解释

读取规则解释

1.阶码不全为0或全为1(规格化数)

2.阶码全为0(非规格化数)

3.阶码全为1,尾数全为0(inf)

4.阶码全为1,尾数不全为0(非数,NaN,Not a Number)

练习

1.浮点数

2.整型存储

a.下面程序的输出为

b.下面两个程序的输出为

c.下面程序的输出为

d.下面两个程序的输出为

e.下面程序的输出为(假设小端环境)


大小端字节序

什么是大小端

首先,我们要知道,整数(short、int、long、long long)在内存中以补码的形式存储,无符号整数(unsigned)在内存中以原始二进制序列存储。

当数据长度小于等于一个字节时 ,很显然计算机就直接存储在一个字节内(内存存储的基本单元是字节)。而大小端字节序,则是超过一个字节的数据在内存中存储的两种方式。

为了更清楚的理解大小端字节序,下面我们创建一个变量a:

#include <stdio.h>

int main()
{
    int a = 0x12345678;
    return 0;
}

我们知道int整型占4个字节,也就是说12、34、56、78会分别存储在4个字节单元中。那么,这4个字节单元在内存中是从高地址向低地址排列还是由低向高就成了一个问题。

我们把78这一头叫做数据的低位字节,12那一头叫做高位字节。那么:

  • 将数据的低位字节存储在内存的高位,就叫大端存储,对应大端机器
  • 将数据的低位字节存储在内存的低位,就叫小端存储,对应小端机器

下面我们在Visual Stodio(x86 Debug)环境下调试上方代码, 并打开内存窗口,观察变量a的内存空间:

这就是将数据的低位字节(78)储存在了内存的低位,是小端存储模式。

我们常用的大多数环境(x86、x64…)都是小端结构( 有计算优势),但是仍然存在大端模式的机器(如KEIL C51)。甚至有些ARM处理器可以让硬件选择采用大端还是小端。
写一个判断大小端的程序

其实很简单,我们截取数字1在内存中的第一个字节即可。

如果输出是1就是小端机器,如果是0就是大端机器。

#include <stdio.h>

int check_sys()
{
	int i = 1;
	return *(char*)&i;
}

int main()
{
	if (check_sys())
		printf("该机器为小端字节序机器\n");
	else
		printf("该机器为大端字节序机器\n");
	return 0;
}

这里先取a的地址、强制类型转换为char*再解引用来取出a在内存中的第一个字节。

注意:这里不能直接将a强制类型转换为char类型来读取第一个字节,因为这样永远只会截取数据最低位的字节,和大小端机器无关。

或者我们也可以用联合体的方式取第一个字节(联合体相关内容在之后的笔记):

int check_sys()
{
    union
    {
        int i;
        char c;
    } u;
    u.i = 1;
    return u.c;
}

浮点数在内存中的存储(IEEE 754规则)

引入

浮点数包括float、double、long double等类型,可写成小数形式(3.14)或科学计数法(1.1E2)

不同浮点数的数据范围在float.h头文件中被规定

下面我们看一段代码:

#include <stdio.h>
int main()
{
	int n = 9;
	float* p = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*p的值为:%f\n", *p);
	
	*p = 9.0;
	printf("n的值为:%d\n", n);
	printf("*p的值为:%f\n", *p);
	
	return 0;
}

这段代码的输出结果为:

n的值为:9
*p的值为:0.000000
n的值为:1091567616
*p的值为:9.000000

明明n与*p在内存中是同一个数,为什么会出现上方的情况呢?

这与浮点数在内存中的存储有关

存储规则解释

浮点数在内存中的存储遵循IEEE 754规则,由电气与电子工程师协会(IEEE)规定

以单精度浮点数为例,我们将其分为3个部分存储在内存中(都是01组成的二进制):

  • 符号位S:1位,0代表正数,1代表负数
  • 阶码E:8位,就是科学计数法的指数部分加127(因为其表示精度的是-126次方到127次方,要加上127让阶码从数字1到254便于存储,因此单精度浮点数也叫余127码)(阶码0与255有特殊含义,见下方读取相关内容)
  • 尾数M:23位,就是科学计数法中数字小数点后的部分

以数字5.0为例:

  1. 其为正数,则S=0
  2. 其可以表示成二进制科学计数法1.01*2^2,则尾数M为01000000000000000000000
  3. 其科学计数法指数为2加上127得到阶码E=129=10000001(二进制)
  4. 合起来就能得到数字5.0在内存中的存储:0100 0000 1010 0000 0000 0000 0000 0000

对于双精度浮点数,其规则与单精度浮点数类似,但是阶码变为11位(余1023码),尾数变为52位。总字节数由4字节变为8字节。

读取规则解释

读取时有3种情况:

1.阶码不全为0或全为1(规格化数)

读取时阶码减去127(或1023)得到指数部分,尾数加1得到数字部分

所以说单精度浮点数规格化数的指数范围是-126到127

2.阶码全为0(非规格化数)

读取时阶码加一再减去127(或1023)得到指数部分(加一使浮点数取值连续),尾数不加1,用于表示极其接近0的数字

如果尾数也全为0,则代表浮点数的±0

3.阶码全为1,尾数全为0(inf)

被判定为浮点数的无穷,正负由符号位决定,用代码inf表示

4.阶码全为1,尾数不全为0(非数,NaN,Not a Number)

用代码NaN表示,用于表示异常数据(比如某个数除以0就会返回NaN,也有可能输出IND-indeterminate不确定的)

练习

1.浮点数

这时上面浮点数存储开头的那一段代码就好理解了

首先第一部分将整型9当做浮点数输出,整型9在内存中存储为:

0000 0000 0000 0000 0000 0000 0000 1001

将其当做浮点数,则S=0,阶码E=00000000,由上面非规格化数内容我们知道这是一个趋近于0的数,所以输出了0.000000

第二部分将浮点数9.0当做整数输出,浮点数9在内存中存储为:

0100 0001 0001 0000 0000 0000 0000 0000

将其当做整型输出即补码转换为原码为:1091567616

2.整型存储
a.下面程序的输出为
#include <stdio.h>

int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

就是很简单的截取,输出a=-1,b=-1,c=255

b.下面两个程序的输出为
#include <stdio.h>

int main()
{
	char a = -128;
	printf("%u\n", a);
	return 0;
}
#include <stdio.h>

int main()
{
	char a = 128;
	printf("%u\n", a);
	return 0;
}

两个程序的输出结果均为4294967168

也是简单的整型提升的问题

比如第一段程序-128的补码为1111 1111 1111 1111 1111 1111 1000 0000

截取到a为1000 0000,整型提升回1111 1111 1111 1111 1111 1111 1000 0000

其直接二进制转换十进制为4294967168

第二段等价,对于char来说127之上就循环回到-128,所以128与-128在这里没有区别

c.下面程序的输出为
#include <stdio.h>

int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}

此代码输出为255

同样的,对于char类型,-128在减一就循环回到了127。所以这里就是从-1一直降到-128,在从127降到1(strlen遇到“\0”结束,其ASCII码为0,所以之后的没意义)

d.下面两个程序的输出为
#include <stdio.h>

unsigned char i = 0;
int main()
{
	for (i = 0; i <= 255; i++)
	{
		printf("hello world\n");
	}
	return 0;
}
#include <stdio.h>

int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i);
	}
	return 0;
}

这两段代码都是死循环,很简单

e.下面程序的输出为(假设小端环境)
#include <stdio.h>

int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

其输出结果为4,2000000(有可能引发读取访问权限冲突)

很好理解,指针1减一指向数组第4个元素,指针2指向第一个元素向后偏移一位字节,也就是略过了数字1内存第一个字节又加上了数字2内存第一个字节。在小端环境下即为0x02000000


JetLinks社区版VS企业版:手把手教你用PostgreSQL+Redis搭建物联网中台(Win7实测) 本文详细对比了JetLinks社区版与企业版的核心差异,并提供了在Windows 7系统上,使用PostgreSQL和Redis搭建物联网中台的完整部署教程。文章深入解析了从环境准备、后端服务构建到前端部署的每一步,为开发者在资源有限环境下构建高性价比物联网平台提供了清晰的实战指南。 阅读详情

相关推荐

SAP STO流程实战:如何配置外向交货单PGI后自动生成内向交货单(附避坑指南)

本文详细解析了SAP STO流程中,如何配置实现外向交货单发货过账(PGI)后自动生成内向交货单。通过分步指南,重点阐述了SPED输出类型、输出条件记录、收货点及确认控制码等关键配置,并提供了针对“No goods receipt possible”等常见错误的避坑指南,助力实现跨公司物料转移流程的自动化与高效衔接。

weixin_28327051的博客 395

浮点数/float/double 是否需要考虑网络字节序的问题

在网络上传输数据时,对整数,我们使用转换为网络字节序的方法,来保证跨平台传输数据时不会出现字节顺序问题导致的解析错误,但是对浮点数,是否也需要这样做?在socket编程中,只有针对整型的字节顺序转换函数,例如htonl(),htons()等,浮点数怎么办?这里先转载一段网上摘取的文章:_______________________________________________________________________________问:为什么在网络编程中,即需要考虑字节序的问题时。对于double、

编码无悔 1万+

【黑马-产品经理入门基础课笔记】01.认识产品经理

问题定义 ==> 可行性研究 ==> 需求分析。

2401_88466092的博客 1841

double类型数据的网络字节序转换

标题关 于C/C++所碰到的一些问题总结** 最近,需要将一套linux开发程序移植到另外一块开发板上,程序中涉及到了网络通信,且所用开发板的处理器为大端模式,之前为小端模式,因此在数据传输的过程中需要考虑到大小端转换的问题。 全新的界面设计 ,将会带来全新的写作体验; 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示; 增加了 图片拖拽 功能,你可以将...

luoqingmumu的博客 6738

Claude Code与Codex深度对比:终端AI编程助手选型指南

大语言模型驱动的AI编程助手已成为开发者提效的重要工具,它们基于自然语言交互,自动完成代码生成、重构和调试。这类工具依赖上下文理解与工程实践,不同产品在交互模式、模型接入和任务执行上差异显著。从终端CLI编程场景出发,梳理AI编程助手的设计原理与技术价值,重点对比Anthropic Claude Code与OpenAI Codex在安装配置、上下文管理、第三方模型接入(如DeepSeek)以及高频报错处理上的实际表现。无论你是新手还是资深工程师,理解这些差异有助于根据自身工作流选择合适工具,或在两者间灵活切

weixin_33755649的博客 3172

保姆级拆解:HP 1312NF/CM1415打印机进纸离合器清洁与更换全记录(附B站/油管视频指路)

本文详细记录了HP 1312NF打印机进纸离合器故障的诊断与修复全过程,包括故障判断、工具准备、拆解步骤、清洁更换技巧及预防措施。特别针对离合器内部海绵老化粘连问题,提供了电工胶布和硬纸片两种实用替代方案,并附有B站/油管视频指路,帮助用户轻松完成打印机维修。

weixin_31102231的博客 375

浮点数通信

浮点数通信

weixin_58619062的博客 1038

EMC基础知识总结

电磁干扰(Electromagnetic Interference),简称EMI,有和两种。传导干扰主要是电子设备产生的干扰信号通过导电介质或公共电源线互相产生干扰;辐射干扰是指电子设备产生的干扰信号通过空间耦合把干扰信号传给另一个电网络或电子设备。

学海无涯的专栏 1366

数据储存:字节序,整形储存。浮点数储存

数据存储

qq_43551810的博客 303

C#与欧姆龙PLC 通信——Fins Tcp协议

该调试助手专门为了帮助大家学习以及测试Fins-Tcp通信,下面进行详细介绍。

qq_34059233的博客 2082

【ComfyUI】QwenImageEdit OOTD角色与姿态匹配换装

本文介绍了一个基于Qwen Edit OOTD 2.0的ComfyUI工作流,能够实现角色与姿态匹配的智能穿搭生成。该工作流通过整合模型推理、姿态识别、图像拼接和渲染等节点,完成从角色图、姿态图到成品穿搭图的完整生成流程。核心采用Qwen Image系列模型进行图像理解和编辑,配合ControlNet进行姿态引导。用户只需提供角色图和姿态参考图,系统即可自动完成姿态解析、语义编码、采样生成等步骤,输出与输入姿态一致的穿搭图像。该方案适用于虚拟角色展示、电商试穿等场景,能保持角色特征一致的同时灵活变换姿态,显

Mr数据杨 1584

1.大小端的定义 2.整数的存储 3.浮点数的存储

整型类型、浮点型类型的存储规则及方法

Mr_Song_student的博客 276

Android影像系统架构专家面试指南

传音控股招聘影像系统架构专家,要求8年以上开发经验,5年架构设计经验,精通Android Camera开发及性能优化。该职位需负责手机影像软件架构设计、技术选型及跨平台适配,重点解决"快稳省"体验优化。面试评估聚焦三大维度:技术方面考察HAL层架构设计、多帧合成优化等能力;系统开发关注低光降噪等场景的算力平衡;团队管理侧重跨部门协作与项目交付。候选人需展现对CamX-CHI等架构的深入理解,具备量化分析性能指标的能力,并能主导旗舰机影像项目全周期落地。

郑伟强dev的专栏 943

IEEE 754浮点数简介与C代码实现

IEEE 754浮点数简介与C代码实现、笔记分享

m0_51004490的博客 7139

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数据在内存中的存储

在解释大小端之前,我们先看一个例子在调试中得到如下结果,以字节为单位,但是内容倒着注意:1.整数在内存中存储的是二进制的补码2.在调试窗口中观察内存,为了方便展示,显示的是16进制的值3.存储顺序倒过来了!!!其实超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下面是具体的概念:大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。

2302_76591114的博客 1981

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

整数和浮点数在内存中的存储(大小端字节序、IEEE 754)

判断是大端模式还是小端模式,IEEE 754标准,浮点数的取出

2302_80868583的博客 1428

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【C语言】浅谈数据的存储

整形和浮点型数据在内存中的的存储方式

a_rong__的博客 201

关于IEEE754 规格数与非规格数的探讨 | IEEE 754-1985 IEEE 754-2008

维基百科: http://zh.wikipedia.org/w/index.php?title=IEEE_754&oldid=32785022英语: http://en.wikipedia.org/wiki/Single-precision_floating-point_format http://en.wikipedia.org/wiki/Double-precision_floating-

作业本 5210

大小端字节序、无符号数的原反补码以及整型提升

1.简单介绍大小端 什么大端小端: 大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中; 小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。 为什么有大端和小端: 为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型32 bit的long型(要看具体.

xaiobit_hl的博客 1123

浮点数在内存中的存储

E是无符号整数,对于32位的浮点数,其取值范围为0~255,对于64位的浮点数,其取值范围为0~2047。并且当E全为0时,E=1-127(或1-1023),则该浮点数无线接近于±0,所以规定当E全为0时,该浮点数为0.当E全为1时,该浮点数±无穷大。对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M 对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。整数在内存中是以大端字节序或小端字节序的方式存储。

2301_76515294的博客 671

IEEE 754浮点数十六进制相互转换 (32位 四字节 单精度)

共用体的内存对齐确保了无论哪个成员被访问,都能满足该成员类型的对齐要求,从而优化内存访问效率。在设计需要处理不同数据类型但不会同时使用它们的情况时,共用体是一个非常有用的工具。

m0_73640344的博客 4519

数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)

数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)

秋刀鱼不做梦的编程日常 1497

深入浅出浮点数

深入浅出浮点数Floating Point Number In a Nutshell深入浅出浮点数Stephen Suen浮点数(Floating Point Number)计算机系统中用于表达实数或者说小数的一种方式。由于其表达方式的原因,产生了围绕浮点数的许多常见问题。最典型的就是"为什么我的浮点运算的结果和想象的不同",即浮点数精度损失问题。本文将回避关于浮点数枯燥的数值计算

longjuanfeng2011的专栏 1797

C语言-数据在内存中的存储

字节序:是以字节为单位,讨论存储顺序的小端字节序存储:把一个数据的低位字节的内容,存放在低地址处,把一个数据的高位字节的内容,存放在高地址处。大端字节序存储把一个数据的低位字节的内容,存放在高地址处,把一个数据的高位字节的内容,存放在低地址处。

sushang的博客 417

C++解析IEEE754 float协议

具体来说,我们先将输入数据的高8位存储到`bytes[0]`中,次高8位存储到`bytes[1]`中,以此类推,最低8位存储到`bytes[3]`中。然后,我们通过访问`fd.f`来获取解析后的`float`类型数值。在`main`函数中,我们定义了一个输入数据`data`,它的十六进制表示为`0x40490FDB`。在上面的代码中,我们定义了一个联合体`FloatData`,它包含一个`float`类型的成员变量`f`和一个长度为4的`unsigned char`类型的数组`bytes`。

zw_ggr_2017的博客 539

大端方式和小端方式 定点数的运算 浮点数的运算

浮点数运算 数据与储存 定点数运算 笔记

builie0748594740的博客 1272
上一篇: 椋鸟C语言笔记#25:内存函数
下一篇: 椋鸟C语言笔记#27:字符串数字提取(atoi、atol、atoll、atof)
椋鸟Starling
博客等级 码龄3年 447粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椋鸟Starling

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值