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的参数,也是同样的原因。

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


审核编辑:刘清

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

    关注

    1

    文章

    514

    浏览量

    57539
  • 数据存储
    +关注

    关注

    5

    文章

    895

    浏览量

    50584
  • 浮点数
    +关注

    关注

    0

    文章

    58

    浏览量

    15792
收藏 人收藏

    评论

    相关推荐

    labview里单精度浮点数和十六进制数如何相互转换?

    我需要将个单精度浮点数(如0.33)转换为十六进制数然后通过串口发送,同时还需将串口读取的十六进制数转换为单精度浮点数。 求问在labv
    发表于 10-14 11:04

    浮点数如何存储?

    浮点数如何存储玩转浮点数
    发表于 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 4167次阅读
    <b class='flag-5'>浮点数</b>常用的编码方法

    modbus 如何读取浮点数

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

    单片机浮点数运算的源码设计

    单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。本文详细介绍了浮点数在单片机中的表示方式和汇编子程序,浮点数比定点数加减法要困难,但是克服了定点数表示范围小
    的头像 发表于 03-07 15:19 9542次阅读
    单片机<b class='flag-5'>浮点数</b>运算的源码设计

    Xilinx怎么定点数浮点数

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

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

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

    什么是浮点数

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

    C浮点数与字符转换工具

    C浮点数与字符转换工具免费下载。
    发表于 06-19 18:17 0次下载

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

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

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

    精度和双精度是计算机中表示浮点数的两种不同的精度。在计算机中,浮点数用来表示带有小数部分的实数,而单
    的头像 发表于 12-15 10:25 2581次阅读

    modbus浮点数怎么读取

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

    一文带你秒懂IEEE 754浮点数

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