数据的存储(2)——浮点型

news2024/11/28 0:34:24

前言:内容是关于浮点型在内存中的存储详解及例子

数据的存储(1)——整型(点击即跳转)

浮点数的存储规则

任意一个二进制浮点数可以表示成以下形式:

(-1)^S * M * 2^E

(-1)^S表示符号位,当S=0,它为正数,因为(-1)^0=1

                                当S=1,它为负数   因为(-1)^1=-1

M表示有效数字,1<=M<2

2^E表示指数位

以十进制的5.0为例:

写成二进制(小数点前的部分和小数点后的部分各自表示):101.0

理解:小数点前要表示5->  1      0    1

                                          2^2 2^1 2^0

           小数点后要表示0.0->   小数点后的二进制的权重从-1开始,一直向后递减

                                                2^-1=0.5 2^-2=0.25

二进制数字101.0 相当于 1.01×2^2,则S=0,M=1.01,E=2
 

类比十进制的101(1.01*10^2)

part 1:单精度float类型的存储

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

part 2:双精度double类型的存储 

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

 part 3:有效数字M和指数E存储和读取(float和double均适用)

有效数字M:

由于1<=M<2,故而M表示成:1.xxxxxx

因为计算机在保存M时,默认这个有效数字M的第一位总是1,因此1会被省去

计算机在保存M时,只会保存M的小数部分,以存储M :1.01为例,只会存储01

计算机在读取M时,会把省略掉的1加上

指数E:

存储:存入E的真实值时需要加上一个中间数,对于8位的E(float)中间数是127

                                                                           对于11位的E(double)中间数是1023

比如:2^10  E=10,存入内存中的E(保存成32位的浮点数):10+127=137即1000 1001

读取:分三种情况

1 E不全为0或不全为1
E的存储值-127(or 1023)得到真实值

此时浮点数的表示规则

1 指数E的存储值减去127(or 1023),得到真实值
2 有效数字M前加上第一位的1

以十进制的0.5为例

二进制形式:0.1 由于规定正数部分必须为1,故而我们要将小数点右移一位,变成:1.0*2^( -1)

保存成32位的浮点数:S=0,E=-1+127=126 (二进制形式:0111 1110), M=0

0 01111110 00000000000000000000000

2 E全为0

E等于1-127(或者1-1023)即为真实值

此时浮点数的表示规则

1 指数E=1-127(or 1-1023)得到真实值

2 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数

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

例子

double类型数据的存储和float类型数据的存储相似,这里以float类型的数据为例

float类型数据的存储:

int main()
{
	float f = 5.5f;
	//5.5(十进制)->101.1(二进制)->(-1)^0 * 1.011 * 2^2(科学计数法)
	//S=0 M=1.011 E=2
	//float(32位浮点数的存储): S存0 M存011 E存2+127=129
	//0 10000001 01100000000000000000000
	return 0;
}

float类型数据的读取:

1 发现E不是全0 or 全1,E=存储值-127=129-127=2

2 M=1+0.11=1.11

3 S=0 故而还原成 (-1)^0 * 1.011 * 2^2

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
*pFloat的值为:0.000000


num的值为:1091567616
*pFloat的值为:9.000000

我们先看前4行代码:

    int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);

以整型的形式存储9,以整型的形式读取打印,结果自然是9

 以整型的形式存储9,以浮点型的形式读取打印,结果是0.000000

理解:


	int n = 9;
	//00000000 00000000 00000000 00001001  -9的补码/原码(以整型的形式存储)
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	//以整型的形式读取打印结果为9
	printf("*pFloat的值为:%f\n", *pFloat);
	//以浮点型的形式读取打印:
	//0 00000000 00000000000000000001001
	//S    E          M
	//发现E全为0,故而E的真实值=1-127=-126 M=0. 00000000000000000001001
	//即(-1)^0 * 0. 00000000000000000001001 * 2^(-126)
	//最终以浮点型的形式打印的结果是:0. 000000

再看后三条代码:

   *pFloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);

以浮点型的形式存储9.0,以浮点型的形式读取打印,结果自然是9.000000

以浮点型的形式存储9.0,以整型的形式读取打印,结果是1091567616

理解:

    *pFloat = 9.0;
	//以浮点型的形式存储:
	//1001.0->(-1)^0 * 1.001* 2^3 
	//S=0 M=1.001 E=3
	//存储时:S存0 M存001 E存3+127=130
	//0 10000010 00100000000000000000000
	printf("num的值为:%d\n", n);
	//以整型的形式读取,打印的是原码,由于最高位是0,则此数为正数,原码,反码,补码相同
	//打印的结果就是由01000001000100000000000000000000转成的十进制形式:1,091,567,616

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业数字化转型该怎么做?有效工具有哪些?

数字化转型的有效工具有哪些&#xff1f;简单来说&#xff0c;企业数字化转型的工具&#xff0c;可以划分为两大阶段—— 第一阶段是传统的IT软硬件&#xff0c;比如传统的ERP系统等第二阶段是与最新数字化技术相匹配的软硬件&#xff0c;比如“SaaS平台”、“低零代码平台”等…

数据结构与算法基础-学习-13-线性表之链队

一、个人理解链队是线性表的衍生之一&#xff0c;具有先进先出的特性&#xff0c;在队尾进行插入操作&#xff0c;在队头进行删除操作。链队由于是动态扩容的&#xff0c;需要新的数据节点时&#xff0c;分配一个&#xff0c;所以不存在顺序队的真上溢情况。链队删除队头节点&a…

点击化学交联剂1807518-78-0,Propargyl-PEG1-SS-PEG1-t-butyl ester,丙炔单乙二醇二硫键单乙二醇叔丁酯

1、基础产品数据&#xff08;Basic Product Data&#xff09;&#xff1a;CAS号&#xff1a;1807518-78-0中文名&#xff1a;丙炔-单乙二醇-二硫键-单乙二醇-叔丁酯英文名&#xff1a;Propargyl-PEG1-SS-PEG1-t-butyl ester 结构式&#xff08;Structural&#xff09;&#xff…

176、【动态规划】leetcode ——1143. 最长公共子序列(C++版本)

题目描述 原题链接&#xff1a;1143. 最长公共子序列 题目描述 本题和 718. 最长重复子数组&#xff08;动态规划&#xff09; 的区别在于此时不要求令一个数组中元素连续。 动态规划五步曲&#xff1a; &#xff08;1&#xff09;dp[i][j]含义&#xff1a; 截止到text1[i …

前端编译、JIT编译、AOT编译

一、前端编译&#xff1a;java设计之初就是强调跨平台&#xff0c;通过javac将源文件编译成于平台无关的class文件&#xff0c; 它定义了执行 Java 程序所需的所有信息&#xff08;许多Java"语法糖"&#xff0c;是在这个阶段完成的&#xff0c;不依赖虚拟机&#xff…

将多个springboot项目的pom.xml文件整合

将多个springboot项目的pom.xml文件整合 0.0、前因 ​ 刚入公司敲代码时、发现一个项目中会包含多个子项目、每个子项目会代表一个功能模块、这属实是把我这个菜鸟惊叹到了。而这种分而治之的方式也引申出一个问题&#xff1a;各子项目的依赖如何统一管理&#xff1f; ​ 我…

Linux:基于bufferevent epoll tcp客户端代码

基于bufferevent epoll tcp客户端代码: include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <event2/event.h> #include <event2/buffere…

在外包干了几年,感觉自己都快费了

先说一下自己的情况。大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近2年的点点点&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了五年的功能测试…

JavaEE-初识Servlet

目录Servlet 是什么?完成一个servlet程序1.创建一个maven项目2.引入依赖3.创建目录4.编写Servlet代码5.打包6.部署7.验证程序第三方工具简化Servlet 是什么? Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app. …

项目难点——【3】分布式任务调度、线程池使用、视频转换

项目难点——【3】分布式任务调度、线程池使用、视频转换 我们有时候在处理视频文件的时候会遇到视频格式转换问题。 1 分布式任务调度 在项目开发中我们想要提升我们项目响应的速度或者想要服务器高效处理一批任务&#xff0c;这个时候就有两种方式&#xff1a; 多线程&#x…

(18)目标检测算法之数据集标签格式转换:json2txt、xml2txt

目标检测算法之数据集标签格式转换&#xff1a;json2txt、xml2txt 目标检测最常见的模型&#xff1a;YOLO&#xff0c;常见的几种标注方式&#xff1a;矩形框、旋转矩形框、实例分割中的多边形标注等类型&#xff0c;根据其标注标签&#xff0c;目标检测主要有以下两种转换方式…

快速读懂网络拓扑图

快速读懂网络拓扑图几重常见的网络拓扑总线型拓扑简介优点缺点环型拓扑简介优点缺点星型拓扑简介优点缺点网络层级机构节点结点链路通路不同的连接线代表什么意思&#xff1f;不同颜色、粗细的直线代表什么意思&#xff1f;闪电线-串行链路几重常见的网络拓扑 总线型拓扑 简介…

创建项目(React+umi+typeScript)

项目框架搭建的方式react脚手架Ant-design官网一、安装方式npm二、安装方式yarn三、安装方式umi devreact脚手架 命令行&#xff1a; npx create-react-app myReactName项目目录结构&#xff1a; 浏览器运行&#xff0c;端口号3000&#xff1a; Ant-design官网 一、安装方…

zk-STARK/zk-SNARK中IP,PCP,IPCP,IOP,PIOP,LIP,LPCP模型介绍

我们的目标是构造 zkSNARK。在我们的目标场景中&#xff0c;Prover 只需要发送一个简短的证明字符串给 Verifier&#xff0c;而 Verifier 不需要给 Prover 发送任何消息。 直接构造一个满足这个场景的 zkSNARK 可能会很困难。一个更灵活的方式是在先在理想模型下构造证明系统&…

SocketPro完整使用教程分享,手把手指导

SocketPro是一款外贸与跨境业务&#xff0c;设计师&#xff0c;海外留学生经常使用的工具。 那么&#xff0c;到底该如何使用SocketPro这款工具&#xff0c;实现自己的业务需求呢&#xff1f;这里放一个以前其他大佬关于SocketPro使用体验的测评: 上面的SocketPro使用测评&…

【Java并发编程】线程安全(一)Synchronized原理

Synchronized底层实现 简单来说&#xff0c;Synchronized关键字的执行主体是线程对象&#xff0c;加锁是通过一个锁对象来完成的是&#xff0c;而锁对象底层关联了一个c源码的monitor的对象&#xff0c;monitor对象底层又对应了操作系统级别的互斥锁&#xff0c;同一时刻只有一…

历时半年,我终于阿里上岸了,附面经和Java非科班学习心得

个人经历 本科双非化学&#xff0c;跨考了电子硕士&#xff0c;研究生依然双非。无互联网实习&#xff0c;无比赛无论文。&#xff08;研究生研究方向是车辆电子和楼宇自动化&#xff0c;有自动化和高校实训讲师相关的实习经历&#xff09; 21年11开始学Java准备秋招。 阿里上…

你真的懂二分法吗?

二分法 二分法非常让我们头痛&#xff0c;不论对于初学者&#xff0c;还是对于有一定编程经验的人来讲&#xff0c;我们都会以为这个思想很简单&#xff0c;而不去在意&#xff0c;可是在实际运用中我们在处理边界条件的时候&#xff0c;往往会要不写出了死循环&#xff0c;要不…

NVM安装与配置教程

一、NVM简介 在项目开发过程中&#xff0c;使用到vue框架技术&#xff0c;需要安装node下载项目依赖&#xff0c;但经常会遇到node版本不匹配而导致无法正常下载&#xff0c;重新安装node却又很麻烦。为解决以上问题&#xff0c;nvm&#xff1a;一款node的版本管理工具&#xf…

Mysql 索引(一)—— 主键索引的底层原理

索引的作用是提升Mysql的检索速度。 如果没有索引&#xff1a;若我们要在几百万条记录中找出一个名为“张三”的人&#xff0c;这个时候我们只能逐条遍历记录&#xff0c;直至找到这个人&#xff1b;如果有索引&#xff1a;假设名为“张三”的人所在记录的索引为 999&#xff…