首页 > 系统相关 >浮点数在内存中的存储及精度问题

浮点数在内存中的存储及精度问题

时间:2024-03-20 23:30:18浏览次数:24  
标签:10 存储 浮点数 计数法 内存 127 精度

1.引子

通过上图,我们发现即使是在我们看来字节大小、实际意义一样的数据,以浮点数、整数两种不同的形式进行存放、取出结果是不同的值,这就说明计算机对浮点数与整数是完全不同的处理方式。毕竟我们都知道计算机是只能识别二进制,因此如何表示小数以及用科学计数法表示数中的点后数以及10的次方就是个值得仔细规划的问题。

2.浮点数的存储

1.浮点数转化为二进制

与整数一样,浮点数也可以根据2的权重转换成二进制,后面乘对应的2的次方即是科学计数法的表示形式

类似于十进制下浮点移动,后面乘上对应10的次方,二进制下科学计数法也是如此,上图101.1还可以进一步化成如下形式

2.S、M、E的存储空间规定

如果我们仔细思考就会发现所有的浮点数都可以表示成这样形式,那么唯一在变的其实就是S、M、E,因此浮点数我们只要存储好这三者就行了。

3.浮点数的存入的特殊规定

1.针对M的特殊规定

前文说过任何数都可以表示成类似科学计数法的表示形式,M必然是1.xxxxx的形式,那么在存储的时候,1其实就显得多余了,因此存储的时候1.xxxx的‘1’就是默认存在的,省略不存,内存中只会存入后面的.xxxxx的部分,如1.01,最终只会存入01,取出的时候将前面的‘1’加上,这样存就会多出1bite的空间,我们存储的精度就更大了。


2.针对E的特殊规定

首先E被规定无符号整数,这意味E为8位,那么它的取值范围是0~255,如果是11位,那么它的取值是0~2047,但是我们知道科学计数法的指数位应该是可以出现负数的,所以IEEE 754规定存入时必须加上一个中间数,对于8位的E,这个中间数就是127;对于11位的E,这个数就是1023.如存储2^10,E为10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

注:对于有效位数为0的情况,我们要可以用0补齐到M对应存储位。如0.5 的⼆进制形式为0.1,由于规定正数部分必须为1,即将⼩数点右移1位,则为1.0*2^(-1),其阶码为-1+127(中间值)=126,表⽰为01111110,⽽尾数1.0去掉整数部分为0,补⻬0到23位,如以下形式:
0 0111111000000000000000000000000
(因为从左往右2的权重是逐渐减小的,0是加载数字后面的)。

4.浮点数特殊的取出规定

1.E不全为0或1的情况:

将解码减去对应127或者1023得到E,再将有效数字M前面补上1,最后根据S判断数据的正负。

2.E全为0:

E为全0,则E的真实值为-127,则源数据为

,这是一个无限接近于0的数,实际就为0.xxxxxxxxxx,因此规定1-127即为真实值E,有效数字M不再加上第⼀位的1,而是还原为0.xxxxxx的⼩数。这样就表示了表⽰±0,以及接近于0的很⼩的数字。

3.E为全1

这是阶数很大,如果有效数字M全为0,则表⽰±⽆穷⼤(正负取决于符号位s);

注:因为E是unsigned int 所以E仍然存在取值范围,不可能表示出所有数。

3.浮点数存储精度

1.精度丢失

其实上述的存储看似万无一失,但是当我们多输入一些数字

我们会发现当精度特别小的时候,我们的数值看起来就变不太一样了,因为其实二进制表示十进制时,对于0.xxxx后面的xxxxx部分是通过2的负次方来表示的,但是这种表示方法就会出现部分数无论怎么往后凑,都会差一点,甚至无限下去,因此,有的浮点数实际上计算机跟我们人看到的不一样,对于这些数,计算机会根据精度来确定数字具体多少。如0.1,如精度只有0.1,那它就是0.1,但是当精度到0.50时,它就不是0.1了。

2.浮点数的比较

因为前面说的精度丢失问题,浮点数间不能用==直接比较大小

那么针对这种情况,我们该如何比较呢?浮点数只能使用差值与规定精度进行比较


1.自定义精度下的差值比较

2.系统精度下的差值比较

标签:10,存储,浮点数,计数法,内存,127,精度
From: https://blog.csdn.net/2401_82610555/article/details/136813390

相关文章

  • C++ 多重继承下的内存布局
    1.多重继承多重继承示例代码如下:classBase1{public:voidf0(){}virtualvoidf1(){}inta;};classBase2{public:virtualvoidf2(){}intb;};classDerived:publicBase1,publicBase2{public:voidd(){}voidf2(){}......
  • 计算浮点数的差
    浮点数不是完美精确的表示,尤其是在涉及到舍入误差和不同数值规模时。一般实现:fabs(a-b)<epsilon这种通过比较差的绝对值来判断浮点数是否相等的方法,存在一些潜在的问题:误差累积:在连续的浮点数运算中,误差可能会逐步累积。这会导致最后的结果偏离真实值,这样用差值来比较就......
  • JMeter压测存储过程
    背景压测后端接口时性能表现不佳,而恰好这个接口是调用DB存储过程进行处理数据,可以分别对存储过程和后端接口进行压测,并对比性能数据,了解分析性能瓶颈。前置下载:mysql-connector-j-8.3.0.jar,放置到jmeter\lib\ext目录下注:测试不同的数据库下载不同的jar包引入jmeter配置执行......
  • [转帖]JVM优化之调整大内存分页(LargePage)
    https://nowjava.com/article/31311 在这篇文章中:内存分页大小对性能的提升原理调整OS和JVM内存分页cat/proc/meminfo|grepHugeecho4294967295>/proc/sys/kernel/shmmaxecho154>/proc/sys/vm/nr_hugepages本文将从内存分页的原理,如何调整分页大小两节......
  • 【C语言】结构体的内存对齐问题
    1.结构体内存对齐我们已经基本掌握了结构体的使用了。那我们现在必须得知道结构体在内存中是如何存储的?内存是如何分配的?所以我们得知道如何计算结构体的大小?这就引出了我们今天所要探讨的内容:结构体内存对齐。1.1对齐规则首先得掌握结构体的对齐规则:1.结构体的第⼀......
  • [转]Garnet: 力压Redis的C#高性能分布式存储数据库
    今天看到微软研究院开源了一个新的C#项目,叫Garnet,它实现了Redis协议,可以直接将Redis替换为Garnet,客户端不需要任何修改。根据其官网的信息,简单的介绍一下它。开源仓库地址:https://github.com/microsoft/garnet文档地址:https://microsoft.github.io/garnet/Garnet是微软研究院基......
  • 数据在内存中的存储
    文章目录数据在内存中的存储整数在内存中的存储大小端字节序存储浮点数在内存中的存储存取数据在内存中的存储整数在内存中的存储整数在内存中是以补码的形式存储的整数的二进制表示有三种:原码、反码、补码对于有符号整数,它的最高位视为符号位,1表示负,0表示正。......
  • 3 python的数值在内存中如何存储
    python的数值在内存中如何存储 在Python中,数值在内存中的存储方式取决于数值的类型和大小,以及Python的版本。Python使用固定的字节数来表示整数类型,并且对于浮点数,通常使用双精度(64位)或者扩展精度(128位)的浮点表示。整数的存储方式:对于较小的整数,Python通常使用一个机器字长......
  • 内存检测工具——ASan(AddressSanitizer)的介绍和使用
    ASan介绍ASan全称AddressSanitizer,是一种内存错误检测工具,目的是帮助开发者检测和调试内存相关的问题,如使用未分配的内存、使用已释放的内存、堆内存溢出等。ASan是由Google开发的,广泛用于C、C++等语言的代码中。ASan的工作原理是在编译时将额外的代码插入到目标程序中,对内存的......
  • 存储引擎
    一、MySQL体系结构连接层:最上层是一些客户端和链接服务,主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。服务层:第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成缓存的查询,SQL的分析和优化,部分内置......