浮点数在内存中的存储

目录

一.回顾:整数在内存中的存储

二.大小端字节序和字节序的判断

什么是大小端 ?

 为什么需要有大小端之分呢?

 判断当前机器的字节序

三.练习 

四.浮点数在内存中的存储 

 数字M

数字E

浮点数取的过程

E不全为0或者E不全为1

 E全为0

E全为1


一.回顾:整数在内存中的存储

整数的二进制表示方式有三种:即原码,反码,补码。

三种表示方式均有符号位和数值位两个部分 ,符号位用0表示正,用1表示负,二进制的最高位被当作是符号位,剩余的就是数值位。

正整数的原,反,补码都相同。

负整数的三种方式不同。

  1. 原码:直接将数字按照正负数的形式翻译成二进制得到的就是原码。的
  2. 反码:符号位不变,其他位依次按位取反就可以得到反码
  3. 补码:反码加1得到的就是补码。s

对于整数来说:数据存放在内存中的是补码。

(详细的讲解可以看我的另一个文章:http://t.csdnimg.cn/LIINU)

二.大小端字节序和字节序的判断

当我们了解了整数在内存中的存储后,我们调试看一个细节:

#include<stdio.h>
int main()
{
	int n = 0x11223344;

	return 0;
}

 运行这个代码,然后我们再进调试。0x+数字,表示这个数字是以十六进制写的。

int类型是4个字节,32个比特位,我们知道一个十六进制的数字可以换算成4个二进制的数字。这里0x11223344,刚好就八位十六进制,也就是32位二进制数据,完全占据这个int。

并且每两个数字结合在一起占据一个字节。也就是11占一个字节,22占一个字节......

在调试时,我们通过内存和监视观察这个int。

 我们会发现在n这个整形中,数据的存储也是44 33 22 11这样的数字。但是我们发现

数据是这样进行存储的,倒着进行存储的,int的四个字节中的第一个字节存储的不是11而是44. 

比如这样: 

什么是大小端 ?

当数据在内存中的大小超过一个字节的时候,这时候就有了存储顺序的问题,根据不同的存储顺序,分为了大端字节序存储和小端字节序存储。

  1. 大端字节序存储:一个数据的低位字节的内容保存在高地址处,而高位字节的内容保存在低地址处,我们就将其称为大端字节序存储
  2. 小端字节序存储:一个数据的低位字节的内容保存在低地址处,而高位字节的内容保存在高地址处,我们就将其称为小端字节序存储

 为什么需要有大小端之分呢?


这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8bit 位,但是在C语⾔中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看
具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了⼤端存储模式和⼩端存储模式。 

 判断当前机器的字节序

#include<stdio.h>
int check_sys()
{
	int n = 1;
	return *((char*)&n);
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

 1的十六进制是0x00000001,如果机器是小端存储,那么int的第一个字节存储的就是01,不然就是00;根据这个我们就可以判断这个机器是什么字节序存储。

三.练习 

#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;
}

 %d是以十进制打印的。

	char a = -1;
	//10000000 00000000 00000000 00000001  -1原码
	//11111111 11111111 11111111 11111110  -1反码
	//11111111 11111111 11111111 11111111  -1补码
	//char只有八个bit位
	//11111111  补
	//10000000  反
	//10000001  原
	//还是-1
	signed char b = -1;
	//char就是signed char所以更上面一样。
	unsigned char c = -1;
	//11111111
	//因为是无符号的,所以原反补相同。
	//二进制的1111 1111是十进制的255

	//还有一种理解就是unsigned char的取值范围是0-255.
	//-1就是0-1,所以就是255
	//如果是-2,就是254
	//同理如果是256就是0
#include <stdio.h>
int main()
{
 char a = -128;
 printf("%u\n",a);
 return 0;
}
	char a = -128;
	//10000000 00000000 00000000 10000000
	//11111111 11111111 11111111 01111111
	//11111111 11111111 11111111 10000000
	//只留8个bit位
	//1000 0000 补码 --- a
	//char类型的数据要发生整形提升,有符号位补符号位
	//11111111 11111111 11111111 10000000
	//%u的形式打印,是认为a中存放的是无符号数

 

打印结果也就是4294967168. 

#include <stdio.h>
int main()
{
	char a = 128;
	//0000 0000 0000 0000 0000 0000 1000 0000 
	//只有8个
	//1000 0000 --- a
	//1111 1111 1111 1111 1111 1111 1000 0000 整形提升
	//%u以无符号整形十进制打印
	printf("%u\n", a);
	return 0;
}

结果和上面那个一样的。

四.浮点数在内存中的存储 

浮点数家族包含:float,double,long double类型。

浮点数表示范围:float.h中定义

首先我们先来观察一段代码:

#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;
}

 

n的值是9,所以第一行打印了9.通过*我们将float所指向的空间的值改为了9.0,所以*float是9.0.

而其他两个为啥是这样的情况呢?

很明显float类型数据在内存中的存储是与整数不同的。

根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式: 

十进制的5.0,写成二进制是101.0,相当于1.01 * 2 ^ 2
那么按照上面的规则S = 0 ,E = 2,M = 1.01;
十进制的-5.0,写成二进制是-101.0。相当于-1.01 * 2 ^ 2
那么按照上面的规则S = 1 ,E = 2, M = 1.01 

对于浮点数来说,他们在内存中的存储并不是纯的二进制,而是S E M.

对于32位的浮点数来说,最高的一位存储符号位S,接着的8位存储E,最后的23 位存储M

对于64位的浮点数来说,最高的一位存储符号位S,接着的11位存储E,最后的52位存储M.

 

 数字M

前面说过M的取值范围是[1,2)。也就是所M可以写成1.xxxxxxxx的形式,其中xxxxxxxx表示小数部分。在计算机保存M的时候,默认第一个数总是1,因此我们可以舍去,只保留后面的小数部分。在读取的时候,我们再加上1,这样的目的是为了节省一位,这样就可以多保留一个数字了。

数字E

首先这个规定,E是一个无符号整形的数字。这意味着E如果是8位,取值范围就是0-255,E如果是11位取值范围就是2047,但是我们只科学计数法中E是可以出现负数的。所以规定再存入E的值的时候必须加上一个中间数,对于8位的E来说这个中间数是127,对于11位的E来说这个数是1023

浮点数取的过程

 指数E从内存中的取出还可以分为三种情况

E不全为0或者E不全为1

这时候就采取 指数E的值减去127(或者1023)得到真实值,再将有效数字M前加上一位1

0.5的存储 

0.5   十进制
0.1   二进制
1.0 * 2 ^-1
S = 0
E = -1
M = 1.0
存入E的时候就是(-1 + 127) = 126
表示为0111 1110
所以0.5的二进制表达方式为0 01111110 00000000000000000000000

 E全为0

 这时,浮点数的指数E等于1-127(1-1023)即为真实值,有效数字M不在加上第一位的1,而是还原为0.xxxxx这样的小数,这样的数字写出来是为了表示+-1(取决于符号位),这样的数字无限接近于0.

E全为1

这时,如果有效数字M不全为0,表示+-无穷大(取决于符号位)。

5.5在内存中的存储

int main()
{
	//5.5
	float f = 5.5f;
	//5.5
	//101.1
	//1.011*2^2
	//(-1)^0 * 1.011 * 2^2
	//S=0
	//M=1.011
	//E=2
	//2+127=129
	//0 10000001 01100000000000000000000
	//01000000 10110000 00000000 00000000
	//40         B0       00       00
	//
	return 0;
}

回到我们一开始看到题目。

#include <stdio.h>
int main()
{
	int n = 9;
	// 00000000 00000000 00000000 00001001
	
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	//以浮点数的视角读取的话
	//0 00000000 00000000000000000001001
	//E为全0,所以这是一个无限接近0的数字。
	printf("*pFloat的值为:%f\n", *pFloat);
	*pFloat = 9.0;
	//1001.0
	//1.001 * 2 ^ 3
	//S = 0
	//E = 3
	//M = 1.001
	//0 1000 0010 00100000000000000000000
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/483042.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud二:核心组件解析

在微服务架构中&#xff0c;Spring Cloud凭借其强大的组件集合&#xff0c;为开发者提供了从服务注册与发现、负载均衡、服务调用到分布式跟踪与日志等全方位的支持。本文将深入解析Spring Cloud的核心组件&#xff0c;通过源码分析和示例代码&#xff0c;帮助读者更好地理解这…

手机实时监控电脑屏幕(手机可以看到电脑在干什么吗)

已经2024年了&#xff0c;假如你还在问我&#xff0c;手机可以看到电脑在干什么吗&#xff0c;有没有手机实时监控电脑屏幕的系统。 那么证明&#xff0c;你可能已经out 了。 现代科技告诉发展的态势下&#xff0c;这种技术已经很成熟了。 域智盾软件就可以实现这种效果↓我们…

『K8S 入门』三:资源调度

『K8S 入门』三&#xff1a;资源调度 一、Label 和 Selector 可以通过 Selector 基于 Label 匹配需要的资源 Label 标签 配置文件中&#xff08;metadata.labels&#xff09;配置 metadata: # Pod相关的元数据&#xff0c;用于描述Pod的数据name: nginx-demo #Pod的名称lab…

微信小程序使用动态ICON让小程序活起来。使用曲线救国方式,非常有效

扫码查看动画效果 当前使用的微信小程序是Skyline模式。webview一样可以使用&#xff0c;而且能更高效的直接替换URL使用。但是由于性能问题&#xff0c;建议在Skyline模式下使用&#xff01; 1、挑选喜欢的ICON 动态ICON官网&#xff1a;18,700 Animated Icons - Lordicon …

MySQL---视图

目录 一、介绍 二、语法 三、视图的更新 四、视图作用 一、介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#…

Stable Diffusion实现光影字效果

昨天下午有人在群里发光影图片&#xff0c;大家都觉得很酷&#xff0c;我没怎么在意。直到早上我在小红书看到有人发同款图片&#xff0c;只是一晚上的时间点赞就超过了8000&#xff0c;而且评论数也很高&#xff0c;也可以做文字定制变现。研究了一下发现这个效果不难实现&…

AbstractQueuedSynchronizer 独占式源码阅读

概述 ● 一个int成员变量 state 表示同步状态 ● 通过内置的FIFO队列来完成资源获取线程的排队工作 属性 AbstractQueuedSynchronizer属性 /*** 同步队列的头节点 */private transient volatile Node head;/*** 同步队列尾节点&#xff0c;enq 加入*/private transient …

docker 数据卷 (二)

1&#xff0c;为什么使用数据卷 卷是在一个或多个容器内被选定的目录&#xff0c;为docker提供持久化数据或共享数据&#xff0c;是docker存储容器生成和使用的数据的首选机制。对卷的修改会直接生效&#xff0c;当提交或创建镜像时&#xff0c;卷不被包括在镜像中。 总结为两…

ctfshow web入门 反序列化

254 分析代码&#xff1a; 如果用户名和密码参数都存在&#xff0c;脚本会创建一个 ctfShowUser 类的实例 $user。 接着&#xff0c;调用 $user->login($username, $password) 方法尝试登录。如果登录成功&#xff08;即用户名和密码与类中的默认值匹配&#xff09;&#…

[AutoSar]BSW_ECUC模块介绍

目录 关键词平台说明一、ECUC 的定义 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)autosar版本4.3.1 >>>>>回到总目录<<<…

iOS UIFont-新增第三方字体

背景 在项目中添加三方字体&#xff0c;是在开发中比较常见的需求&#xff0c;每次新增字体&#xff0c;都会遗忘其中某个步骤&#xff0c;又要去百度一下才能把字体添加使用成功。每次这样有点浪费时间和打击自信&#xff0c;于是便想着&#xff0c;自己好好来理一理新增字体…

Penpad 生态资产 $PDD LaunchPad 在即,Season 2 规则解读

Penpad是Scroll上的LauncPad平台&#xff0c;该平台继承了Scroll底层的技术优势&#xff0c;并基于零知识证明技术&#xff0c;推出了系列功能包括账户抽象化、灵活的挖矿功能&#xff0c;并将在未来实现合规为RWA等资产登录Scroll生态构建基础。该平台被认为是绝大多数项目、资…

[RootersCTF2019]I_<3_Flask -不会编程的崽

又是一个新东西哦。先看界面 源代码没提示&#xff0c;抓包没特别数据&#xff0c;没有交互界面&#xff0c;后台扫描也没文件。我知道是python模板&#xff0c;但是注入点&#xff1f;&#xff1f;&#xff1f;看来wp才知道原来还有参数爆破&#xff0c;哈哈哈。整笑了。有一…

怎么拆解台式电脑风扇CPU风扇的拆卸步骤-怎么挑

今天我就跟大家分享一下如何选购电脑风扇的知识。 我也会解释一下机箱散热风扇一般用多少转。 如果它恰好解决了您现在面临的问题&#xff0c;请不要忘记关注本站并立即开始&#xff01; 文章目录列表&#xff1a;大家一般机箱散热风扇都用多少转&#xff1f; 机箱散热风扇选择…

攻防世界[EASYHOOK]

攻防世界 * 2 题目&#xff1a;EASYHOOK题目地址&#xff1a;[](https://adworld.xctf.org.cn/challenges/list)总结&#xff1a;最后来聊一下hook 题目&#xff1a;EASYHOOK 题目地址&#xff1a; 拿到程序后无壳直接ida32打开&#xff0c;发现逻辑如下&#xff0c;输入长度…

【工具】cassetteai — 制作音乐就像现在写提示一样简单

Cassette 是一种人工智能驱动的音乐创作工具,使各种技能水平的用户都可以根据自己的特定需求和偏好生成高质量、免版税的音乐曲目。它基于基于潜在扩散 (LDM) 的机器学习模型,可以使用用户提供的文本描述来想象节拍。它具有易于使用的界面,用户可以输入各种参数,例如所需的…

Python工具-清理Unity(批量深度)清理U3D项目工程保留关键工程文件

前沿 1. Unity工程越来越多&#xff0c;很久不用的工程里存在了很多无用的大文件夹&#xff0c;极大的影响电脑容量。 2. 我电脑里面U3D工程只有17个&#xff0c;但容量就高达60GB&#xff0c;使用自己编写的工具清理后&#xff0c;减到了30GB多。清理了不是很重要的文件和文件…

基于DA优化CNN-LSTM的负荷预测

今天给大家分享DA优化CNN-LSTM的负荷预测&#xff0c;主要从算法原理和代码实战展开。需要了解更多算法代码的&#xff0c;可以点击文章左下角的阅读全文&#xff0c;进行获取哦~需要了解智能算法、机器学习、深度学习和信号处理相关理论的可以后台私信哦&#xff0c;下一期分享…

基于springboot+vue的电影院购票系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

docker将本地镜像pull到阿里云和registry

目录 一、上次到阿里云服务器 1、制作一个带有vim功能的Ubuntu镜像 2、在阿里云上面创建镜像仓库 3、从阿里云仓库中上传和拉取镜像 二、上传镜像到本地私有库registry 1、下载镜像docker registry 2、运行私有库registry&#xff0c;相当于本地有个私有docker hub。 3…