0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

谈一谈浮点数的精度问题

冬至配饺子 来源:最后一个bug 作者:bug菌 2022-08-11 14:28 次阅读

最近进行代码的review过程中看到同事在代码中直接拿浮点数相等来作为条件,其他同事提醒他的时候,他还迷迷糊糊不知道为什么,所以就有了今天这篇文章。

1、浮点数据的不均匀

我们经常会谈到浮点数的精度问题,float-单精度,double-双精度,double类型相比float类型精度更高,相应的需要的内存字节个数也越多,谈到精度的问题,其实也就说明这种数据类型并不能够连续的标识任何的点,整形数就不用说了,小数部分直接不能标识。

毒王这篇文章基本上可以从浮点数的存储到表意来较好的认识浮点数数据类型,但是中间部分对于浮点数精度部分的介绍并不是很形象,所以今天再详细一点说明一下。

首先我们要认识到通常float类型的变量占据四个字节,而uint32_t的整形类型也是占据四个字节,既然都是四个字节,那他们所能表示的不同数据个数是一样的。

如果不太理解,可以把float看成4个bit,uint32_t也是4个bit,那么他们不管经过什么变换,每个数据类型都只能够标识16个数。

好,如下图以4字节float的数据存储模型所示:

poYBAGL0oKOAGnTXAABXAQp6GqM658.pngpoYBAGL0oK-AFdFKAACbC03w1Nw937.png

4个字节的浮点数,不像无符号整形所有的bit都是数据区,并且以每个数据之间相差1均匀分布,而浮点数把这4个字节分为了不同的区来起到不同的作用,从而用另外一种方式表达数据。

其指数部分越大,表示的数据就越大,但是尾数部分只能表示到23位,这样的话导致数据的精度就越差,如果不太理解可以用一个较大的数通过上面的转换方式进行换算,便能理解。

poYBAGL0oMOAQIDRAABoH8OBdKY496.png

所以同样是4个字节,根据浮点数的表示,越接近0就越稠密,越远离0就越稀疏,呈现一种不均匀的数据排列状态,如上图所示,同样它也也不能标识实轴上任意的点。

2、验证一下不均匀

好了,讲了这么多理论,多多少少得来点程序验证一下:

pYYBAGL0oNWAHNSBAAEPNVlIAkk408.png

看看上面的代码,这还用说,肯定这两个数相等呀,相减也等于0,然而看一下输出结果:

poYBAGL0oOyAdQmtAABx3Fdix3k093.png

结果并不相等,并且相差还不少。

其结果也就说明了浮点数在大数的标识精度不好,只能近似标识,同时也说明了为什么一般不使用浮点数相等来进行判断的原因。

这也是为什么有时候明明我们采用直接编码用准确的浮点数,到了浮点数变量里面却损失了精度,因为4个字节的float标识不了,只能近似处理。

3、非要判断相等

由于有些应用非要使用浮点数进行相等的处理,我们不应该直接使用浮点数进行等于号的判断,而是要在一定的误差和精度范围内进行满足。

poYBAGL0oPuAFqUrAACMOZYGM8M317.png

如上图所示代码是比较常用的处理办法,在往期的文章中,bug菌没有详细的讲解这个误差宏的定义,前面了解到当数据比较大的时候相邻的差值会比较大,这样就存在两个浮点数的差值大于所设置的误差范围而无法判断相等。

所以这样的处理办法来判断浮点数近似相等会存在一些局限性。

那有没有相对更好一点的办法呢?

当然是有的,不然接下来没得写了。

还是要从浮点数的存储和标识出发来处理该问题,既然浮点数天然就存在一定的误差,而有时候计算又无法获得唯一的数值,如下图所示,浮点数计算出来的实轴上的值都会因为浮点数无法存储标识而近似到其相邻的可以标识的数值上。

poYBAGL0oRGAYTzNAAB2XzdRbF0271.png

从浮点的存储模型来看,指数部分代表着浮点数的范围,尾数部分代表着浮点数的精度,那么尾数的最后一位其实就表示了浮点数的当前数值附近的精度。

于是对浮点的近似相等进行了算法上的修改,如下代码所示:

poYBAGL0oSKAZZujAACMlPdwF2U141.png

解释一下 :

如果直接相等,说明浮点数各数据位都相等;而如果不相等可能相邻,于是强制转化为整形,比较尾数最后一位是否不同。

这里使用一个小技巧,采用异或的处理办法,如果其他位都相同,而最后一位不同,结果就等于1,认为两个浮点数近似相等。

本文到此结束,我相信大家应该对浮点数有了一个更加深入的了解,面对一些问题心中也会有一些答案,比如浮点数为什么不能作为switch的参数,也是同样的原因。

但总的来说还是建议大家不要判断浮点数相等,非要用也要特别小心。


审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Switch
    +关注

    关注

    1

    文章

    532

    浏览量

    57869
  • 数据存储
    +关注

    关注

    5

    文章

    941

    浏览量

    50742
  • 浮点数
    +关注

    关注

    0

    文章

    59

    浏览量

    15829
收藏 人收藏

    评论

    相关推荐

    请问如何打印浮点数或双精度变量?

    如何打印 浮点数或双 精度变量?
    发表于07-12 08:24

    官方例程modbus slave rtu,浮点数精度不对是怎么回事?

    官方例程 modbus slave rtu, 浮点数 精度不对,对保持寄存器设置 浮点数,读取到的 浮点数结果
    发表于07-19 08:10

    浮点数如何存储?

    浮点数如何存储玩转 浮点数
    发表于12-30 07:10

    MCU中双精度浮点数是用什么格式存储的?

    MCU中双 精度 浮点数是用什么格式存储的
    发表于10-11 06:24

    浮点数的表示方法

    浮点数的表示方法   浮点数,是指小数点在数据中的位置可以左右移动的数据。它通常被表示成:    N = M* RE  这里的M(Mantissa)被称为 浮点数
    发表于10-13 17:13 1.6w次阅读
    <b class='flag-5'>浮点数</b>的表示方法

    浮点数常用的编码方法

    浮点数常用的编码方法  前面已经说到,在计算机内, 浮点数被表示为如下格式:    通常情况
    发表于10-13 17:21 4327次阅读
    <b class='flag-5'>浮点数</b>常用的编码方法

    modbus 如何读取浮点数

    本文为大家介绍modbus读取 浮点数的两个程序设计。
    发表于02-08 10:03 1.4w次阅读

    Xilinx怎么定点数浮点数

    转化为的 浮点数可以是单 精度也可以是双 精度
    发表于07-05 08:09 3816次阅读
    Xilinx怎么定<b class='flag-5'>点数</b>转<b class='flag-5'>浮点数</b>

    什么是浮点数浮点数在内存中的存储

    浮点型简单讲就是实数的意思。 浮点数在计算机中用以近似表示任意某个实数。
    的头像 发表于11-09 11:07 4441次阅读
    什么是<b class='flag-5'>浮点数</b>?<b class='flag-5'>浮点数</b>在内存中的存储

    什么是浮点数

    Python数据类型第 种:字符串(str)。 Python数据类型第二种:整数(int)。 Python数据类型第三种: 浮点数浮点数的英文名是float, 浮点数没有简写。
    的头像 发表于02-23 14:58 4170次阅读

    点数浮点数的概念浮点数二进制序列与指数表达式之间的转化

    的缺点:由于小数点位置固定不变,定 点数所表示的数的范围非常有限,不能同时表达特别大或特别小的数,所以才出现了 浮点数,以此来扩充数的范围,同时 浮点数也广泛应用于 精度要求高的场合。简单的理
    的头像 发表于08-22 16:06 6013次阅读
    定<b class='flag-5'>点数</b>和<b class='flag-5'>浮点数</b>的概念 <b class='flag-5'>浮点数</b>二进制序列与指数表达式之间的转化

    精度和双精度浮点数的区别

    在计算机科学和数值计算中, 浮点数种用于表示实数的数据类型。 浮点数有两种 精度级别:单 精度和双 精度
    的头像 发表于12-13 10:55 3938次阅读

    精度和双精度浮点数的区别

    。 单 精度 浮点数,也称为单 精度 浮点数格式,用于在计算机中表示32位二进制格式的 浮点数个单
    的头像 发表于12-15 10:25 3838次阅读

    modbus浮点数怎么读取

    Modbus是 种通信协议,常用于工业自动化系统中的设备之间的通信。它支持多种数据类型,包括整数、 浮点数、字符串等。 浮点数在工业领域中广泛应用,因此了解如何读取和处理Modbus 浮点数
    的头像 发表于12-28 14:38 4398次阅读

    文带你秒懂IEEE 754浮点数

    、简介1、常见的 浮点数表示方式是IEEE754标准,它规定了 浮点数的存储格式和运算规则,这个标准定义了两种 浮点数表示:单 精度和双
    的头像 发表于03-18 08:09 5195次阅读
    <b class='flag-5'>一</b>文带你秒懂IEEE 754<b class='flag-5'>浮点数</b>