浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶

2023-10-23 13:50

本文主要是介绍浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者的话
本文涵盖了浮点型在内存中的如何存储、如何取出、为何有精度丢失等知识点~


浮点型概括

常见的浮点型数据有三种:

  1. 以科学计数法表示的:1e10、1.28e10
  2. 数据后加入字符‘f’的:3.14f、7.76f
  3. 不用科学计数法也不加f:1.22、4.89

第一种表示:
1*10^10 和 1.28*10^10
第二种表示:
用float创建的浮点数,要在后面加’f’,不然会默认为double型储。
第三种表示:
用double创建的浮点数,或没加‘f’的float创建数。


浮点数的存储

根据国际标准IEEE754规定,任意的浮点数V都可以表示为以下形式:

  • V=(-1)^S * M * 2^E
  • S等于0或1,是-1的指数位,0则正数,1则负数
  • M等于有效数字,应大于1,小于2
  • E是2的指数位,是一个有范围的正数

例:

  1. V=5.5
  2. V=9.0

首先我们要知道,十进制的小数点右边第一位,表示10的-1次方,同样,二进制的小数点后一位,是表示2的-1次方
则V=5.5可以分解成:101.1
则V=9.0可以分解成:1001.0
随后,将这个分解后的数字转为大于1,小于2的数,并将小数点移动了几位记下来,这将是E的大小

  1. V=1.011,移动2位,E=2
  2. V=1.001,移动3位,E=3

最后,如果是正数,S为0,如果是负数,S为1。

  1. V=(-1)^0 * 1.011 * 2^2
  2. V=(-1)^0 * 1.001 * 2^3

这样,你就知道如何表示一个浮点型的数了,由此可见,一个浮点型的数,其大小只与>S、M、E三个变量有关,所以在内存中对于浮点型的存储,只需要存储这三个变量可。


bit位储存模型

在这里插入图片描述
在这里插入图片描述

  • 第一张图:float的储存模型
  • 第二张图:double的储存模型
  • 图片来自比特科技

这两张图相信以各位的聪明才智,不需过多解释也能看得懂。

我们知道,M是一个大于1,小于2的数,那么不同的M之间只有小数点后面的数不同,如果我们只把M小数点后面的数存起来,取出的时候再加上1,就可以多存一位。
因此,float的M能存24位,double的M能存53位。

此外,对于E的存储,还有一些别的规定:

因为E是一个无符号的数,只能是正数,但是科学计数法中是可以出现负数的,所以IEEE又规定,E在存入时必须加上一个中间值

  • 对于float,E有8位,取值范围为0~255,存入时需加上255/2=127.
  • 对于double,E有11位,取值范围为0~2047,存入时需加上2047/2=1023.

比如:5.5的E是2,存入时需存2+127=129;9.0的E是3,存入时需存3+127=130.


精度丢失

上述我们说到,二进制小数点后1位是2的-1次方,后2位是2的-2次方…

即,一个浮点型的小数点后面的数,只能用0.5、0.25、0.125…等等数来拼凑起来。

若是我给一个3.141592653579,这在有限的M位下是不可能完整精确地拼凑起来的,于是就有了精度丢失
在这里插入图片描述
Look:我把3.14存进a,鼠标放在上面,显示这个数并不是精准的3.14.

这也是为什么,double型能存的数据比float型更为精准。(因为M位更多)


浮点型的取出

  • S的取出:没什么好说的,是1还是1,是0还是0.
  • M的取出:因为只存了小数点后面,取出来后要加上1.
  • E的取出:又分为三种情况,请看细细道来。

1,E全为1,此时若M全是0,则是无穷大,正负看S;若M不全是0,则这个数是NaN(未定义或不可表示的值),至于为什么,我只能说这是未尽事宜,是规定。

2,E全为0,这种情况下在取出E时,float规定E为-126,double规定E为-1022,M取出来后不再加上1,以此来表示一个无限接近于0的数,正负看S。

3,E不全0也不全1,减去127或1023拿出来即可。


浮点数的取出实机演示

在这里插入图片描述
如图,我将5.5f存入a;
在这里插入图片描述
随后,取a的地址进行观察。
因为我当前环境是x86,机器为小端存储。

PS:如果您不明白什么是小端存储,请点击:大小端字节序存储详解

所以a的地址存放的十六进制序列为:40B00000
转换为二进制:0 10000001 01100000000000000000000
观察S、M、E的位置
S:0
E:因为不全是1或全是0,应减去127,0b10000001-127=2
M:0.011+1=1.011
这样,你就把V取出来了。
这时候有同学可能要问了,这把SME三个数装上以后,是1.011*2^2是4.011啊。

请注意:此时是用二进制表示


这篇关于浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/268266

相关文章

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

使用SpringBoot+InfluxDB实现高效数据存储与查询

《使用SpringBoot+InfluxDB实现高效数据存储与查询》InfluxDB是一个开源的时间序列数据库,特别适合处理带有时间戳的监控数据、指标数据等,下面详细介绍如何在SpringBoot项目... 目录1、项目介绍2、 InfluxDB 介绍3、Spring Boot 配置 InfluxDB4、I

Python进阶之列表推导式的10个核心技巧

《Python进阶之列表推导式的10个核心技巧》在Python编程中,列表推导式(ListComprehension)是提升代码效率的瑞士军刀,本文将通过真实场景案例,揭示列表推导式的进阶用法,希望对... 目录一、基础语法重构:理解推导式的底层逻辑二、嵌套循环:破解多维数据处理难题三、条件表达式:实现分支

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作