C语言浮点数相等判定

news/2025/3/12 9:18:39/文章来源:https://www.cnblogs.com/cuzperf/p/18616786

等价关系

按照离散数学的等价关系叙述,集合 \(X\) 上的关系 \(R \subset (X, X)\) 如果满足

  1. 反身性: \((x, x) \in R, \forall x \in X\),自己等于自己
  2. 对称性: 如果 \((x, y) \in R\),则 \((y, x) \in R\),我等于你,则你也等于我
  3. 传递性: 如果 \((x, y) \in R\)\((y, z) \in R\),则 \((x, z) \in R\),我等于你且你等于他,则我等于他

这里考虑 IEEE754 中双精度浮点数(即 C 语言中的 double)相等判定,按照 C 语言中 == 判定,则它确实是等价关系,注意 0.0 == -0.0 虽然它们的二进制表示不同。

由于舍入误差,浮点数使用 == 作为相等判定条件无法满足现实中的要求。例如 0.1 + 0.2 == 0.3 是不成立的(0.1 在二进制中无限循环小数)。

因此一般用绝对误差判定:fabs(x - y) < eps 时认为“相等”,其中 eps 是一个指定的小数。显然它满足反身性和对称性,但不满足传递性:例如取 x = eps/2, y = 0, z = -eps/2。

但绝对误差判定存在另一个问题:\(x = 1.0 + 2^{53} + 1.0\) 不能被精确保存,得到的是 \(2^{53}\),而 \(y = 2^{53} + 2\) 是被精确保存的。那么按照上述判定,它们不相等。

因此再引入相对误差的判定:fabs(x - y) < eps1 || fabs(x - y) < eps2 * fabs(x) || fabs(x - y) < eps2 * fabs(y),其中 eps1 和 eps2 均为指定的小数且一般相等。显然它满足反身性和对称性,但不满足传递性:例如 \(x = (1 - eps2) \cdot 2^n\), \(y = 2^n\), \(z = (1 + eps2) \cdot 2^n\)

于是有如下判定的 C 代码(仅满足反身性和对称性)

#include <math.h>
#include <float.h>int fIsEqual(double x, double y)
{double z = fabs(x - y);return z < DBL_EPSILON * 10 || z < DBL_EPSILON * 10 * fabs(x) || z < DBL_EPSILON * 10 * fabs(y);
}
  1. 其中 DBL_EPSILON 是 1 与比 1 大的最小浮点数之间的差值,按照 IEEE754 标准值为 \(2^{-52}\)
  2. 这里的 10 为经验值,用于误差累计后依然能判过去,另外 DBL_EPSILON * 10 一定会被编译器优化成一个常量
  3. 返回值用 int 不用 bool 是因为 C23 才定义 bool

上述代码中需要做三次判定才能确定不相等,考虑到如果 fabs(x - y) < DBL_EPSILON * 10 * fabs(y) 时, fabs(x)fabs(y) 差距较小,再判断 fabs(x - y) < DBL_EPSILON * 10 * fabs(x) 有损性能,且意义不大。

删掉中间的判定条件,并用 x 的值覆盖 z,就推出下面"优化版"(仅满足反身性,不满足对称性和传递性,假优化请勿使用!!!)

include <math.h>

include <float.h>

int fIsEqual(double x, double y)
{
x = fabs(x - y);
return x < DBL_EPSILON * 10 || x < DBL_EPSILON * 10 * fabs(y);
}

但此时当 \(x = 4503599627370487\)\(y = 4503599627370497\)fabs(x - y) = 10,此时 fIsEqual(x, y) 成立,但 fIsEqual(y, x) 不成立,见下图

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么修改网站admin密码,如何安全地修改网站后台管理系统的admin密码,提升安全性,防止未授权访问

修改网站后台管理系统的admin密码是确保网站安全的重要措施。以下是详细的修改步骤:登录后台管理系统:使用当前的admin账户登录网站后台管理系统。 确保使用的是最新的浏览器,以获得最佳的用户体验。进入用户管理页面:在后台管理系统中,找到“用户管理”或“管理员管理”选…

PbootCMS 织梦支付宝接口常见错误

错误代码 ILLEGAL_PARTNER:更新 PARTNER 值和安全校检码。 确认 PARTNER 值和安全校检码对应且有效。 确认 PARTNER 开通了所需的服务。错误代码 HAS_NO_PRIVILEGE:登录签约的支付宝账号,查询接口服务类型和合同生效时间。 确认服务名称、合同生效时间、合作者身份ID和校验码…

帝国CMS调用标题分类灵动标签

[e:loop={1,5,0,0}] 【<a href="<?=sys_ReturnBqInfoTypeUrl($bqr[ttid])?>"><?=class_tr[$bqr[ttid]][tname]?></a>】 <a href="<?=$bqsr[titleurl]?>" target="_blank"><?=$bqr[title]?>&l…

旅游开发团队协作,什么办公软件能增进默契?

冬季旅游市场具有独特的魅力与挑战,对于旅游公司而言,选择合适的团队协作办公软件至关重要。这些软件不仅要满足日常业务需求,更要契合冬季旅游的特殊情境,如应对旅游高峰期的高效协作、保障寒冷天气下旅游行程的顺利进行等。对于 MBTI 中的 J 人来说,有序、高效且可视化的…

SpringCodel微服务

SpringCodel微服务 docker启动命令: systemctl start docker 启动docker systemctl status docker 查看docker状态 systemctl enable docker 设置开机自启设置容器开机自启 docker update status=aways 容器名docker ps 格式化输出容器内容 (1)--format &qu…

验证云通行证失败, 请求连接无效

新合新公有云登录协同开发平台登录时提示"验证云通行证失败, 请求连接无效", 其他私有环境都正常 解决方案: 需要通过金蝶引导程序更新一下BOS程序

给我2分钟,保证教会你在Vue3中实现一个定高的虚拟列表

前言 虚拟列表对于大部分一线开发同学来说是一点都不陌生的东西了,有的同学是直接使用第三方组件。但是面试时如果你简历上面写了虚拟列表,却给面试官说是通过三方组件实现的,此时空气可能都凝固了。所以这篇文章欧阳将会教你2分钟内实现一个定高的虚拟列表,至于不定高的虚…

盘点2024年10款最热门LLM网关/AI网关

随着人工智能技术的飞速发展,将大型语言模型(LLM)部署到生产环节变得日益复杂。特别是在AI和基于LLM的API需求激增的当下,这一挑战尤为突出。Gartner的预测显示,到2026年,由AI和LLM工具驱动的API需求将激增超过30%,这无疑强调了高效模型管理的重要性。 在这方面,企业面…

第四天案例练习-banner效果

Banner设计:是一种用于展示品牌、产品或服务信息的网络广告设计。 通常以横幅的形式出现在网页或移动端屏幕的顶部,也可以在社交媒体平台上使用<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name=&q…

从5天到1天,某大型国有集团的数智化转型经历了什么?

“只有决策快、公司运营快之后,公司才能实现降本增效”。 从北京到新疆、从中国到南非,从奥运会场馆的水泥混凝土到钱塘江畔拔地而起的高楼房产,无不存在着某大型国有集团的身影。 历经60多年沧桑巨变,该集团已发展成为以“新型绿色环保建材制造、贸易及服务,房地产开发经…

旅游开发流程中办公软件的关键作用,你知晓否?

在旅游行业的运营中,产品设计与客服协作的流畅性直接影响着游客的体验和公司的效益。对于 MBTI 中偏好秩序与规划的 J 人来说,选择合适的可视化团队协作办公软件尤为关键。这类软件能够让旅游业务流程清晰透明,促进各部门高效沟通与协作,提升工作效率与个人学习能力。以下将…

13-MSF常见漏洞复现

1、MS08-067、MS10-018漏洞复现,对比bind和reverse攻击模式的区别MS08-067 环境:使用kali中的MSF工具攻击Windows XP开启msfconsole,搜索MS08-067漏洞,进入漏洞利用模块 msfconsole search ms08-067 use exploit/windows/smb/ms08_067_netapi 查看配置项show options设置相…