比较浮点数的黄金法则 -- The golden rule for floating number comparison

pythonocc基础:OCC.Core.Standard类简介 是 Open CASCADE Technology (OCCT) 库中的一个基础模块,它提供了许多核心的工具和数据类型,支撑着整个OCCT框架的运行。这部分内容涉及内存管理、异常处理、基本数据结构、字符串处理、资源管理等通用功能,是开发基于OCCT应用程序不可或缺的一部分。下面详细介绍其作用及主要库与常用方法。 阅读详情
How to compare floating numbers is an ooold, yet frequently asked, question. Here I am not going to repeat the old answers, since as you know tons of good links are there in the web that explained well how floating number works in computers and how comparisons should in principle be carried out. Instead, I am going to straightly give you a few pieces of code that work universally for IEEE 754 floating numbers, regardless their magnitudes and the comparison rigorosity. They are based on the golden rule as I am going to show you. At the end, I will discuss upon the performance optimization for a few special cases.

OK, here we go. But... wait a second, let me first be super clear of a few of things:
1. I am talking about the IEEE standard 754 floating numbers. This is almost needless to say because this specification is adopted by most, if not all, modern computers. But just to be super clear, I am assuming your computer also works with this specification.
2. I assume that you, the reader, know some basics about floating numbers, such as: floating numbers are not continuously represented in computers.
3. I assume that you, the reader, could read C++ program. This is important since all code and examples here are given in C++.
If any of the three assumptions was broken for your case, then you should not read this article.

Congrats, you passed the "configure" stage. :-) We now set off.

// Compares equality
inline bool is_equal( Real x, Real y )
{
   Real x1  = abs_( x );
   Real y1  = abs_( y );
   Real z1  = (x1 > y1 ) ? x1           : y1;
   Real eps = (z1 > 1.0) ? z1 * epsilon : epsilon;

   return abs_( x - y ) <= eps;
}

This piece of code reveals the golden rule, anything else here are derived from this rule. In this code, Real is a floating number, be it float or double or even long double; abs_ is a function to get the absolute value of a given number, be it a standard function or your own function; REAL_EPSILON is a adjustable parameter representing the rigorosity of the comparison, I will elaborate upon it later. What this code does is to first calculate the proper range within which the two real numbers are considered the same. This is the real thing. Actually all lines before the return statement are dedicated to this task. This range is calculated automatically based on the preset rigorosity as represented by, again, REAL_EPSILON. Once this range is obtained, the remaining of the whole comparison task becomes trivial: just calculate the difference of the two numbers, and then compare the absolute value of this difference with the range; if it is smaller than the range, the two numbers are considered the same; otherwise, different. You may ask why the range is calculated as described? Well, to explain that, you need to learn some basics about the floating number, which I have to skip, as I said.

What really needs to explain here is the value for the rigorosity. What value should it take? You might immediately think of the *_EPSILON macros/constants as defined in <cfloat> library. That is, however, not a very good choice. The reason is that for a given value x, probably only 2 or 3 numbers are considered equal by this rigorosity, which is too rigorous and no much difference from the direct comparison. I recommend a value that is 5-10 times the *_EPSILON for the rigorosity for general applications, but your mileages might be different.

// Compares equality with adjustable rigorosity.
// Slight meta-tricks to figure out REAL_EPSILON for different Reals. Yes, the meta thing is kinda verbose if you don't have some a meta library.
template <typename T>
struct what_real;
template 
< > struct what_real<float> { static const int value = 0; };
template 
< > struct what_real<double> { static const int value = 1; };
template 
< > struct what_real<long double> { static const int value = 2; };
template 
< > struct what_real<my_real> { static const int value = 3; };
extern Real REAL_EPSILON;  // Its value has to be set outside the header, in a .cc file.

namespace {
    
const int GAUGE = 7;
}


inline 
bool is_equal( Real x, Real y, real_epsilon = GAUGE * REAL_EPSILON )
{

...
   Real eps 
= (z1 > 1.0) ? z1 * real_epsilon : real_epsilon;

   
return abs_( x - y ) <= eps;
}

The meta-thing is just added for fun. The main point is that you now can use the function like: is_equal( x, y, 1E-6 ), where 1E-6 is an online specification of the rigorosity. More convenient, huh!?

With the above code understood, we can easily define greater-than and less-than functions (so they are omitted here).

Now let's deal with performance for some special cases. A common case is to compare a floating number against zero. It is better to dedicate a function for this case. Replacing zero to the argument y, we reduce the code to the following:

inline bool is_zero( Real x, real_epsilon = GAUGE * REAL_EPSILON )
{
   
return abs_( x ) <= real_epsilon;
}

That's simple and good. How about for 1, 2, 8, or an arbitrary integer? If we cannot define a different function for each of these values, what can we do? Template is the answer. We can write a code like the following:


namespace {

template 
<bool C, int A, int B>
struct select_value
{
     
static const int value = A;
}
;

template 
<int A, int B>
struct select_value<false, A, B>
{
    
static const int value = B;
}
;

template 
<int X>
struct meta_abs
{
    
static const int value = select_value<(X>0), X, -X>::value;
}
;

}


template 
<int Y>
is_equal_to( x, real_epsilon 
= GAUGE * REAL_EPSILON )
{
   
return abs_( x - Y ) <= meta_abs<Y>::value > 1 ? real_epsilon * meta_abs<Y>::value : real_epsilon;
}


Here in the anonymous namespace, we defined a meta-function for calculation of the absolute value of a given constant integer Y. This transfers part of the calculation to the compile time, optimizing the overall performance of the comparing operation.

That is all I'd like to say regarding the floating number comparison. The remaining is yours.

BTW, not all of the code here were tested with a compiler.
SpringBoot+Vue+Mysql社区医院信息平台(源码+文档) SpringBoot+Vue+Mysql学生宿舍信息管理系统 WEB端软件项目(源码+文档) 项目包含:①完整源码(后端+管理后台+用户前台);②数据库脚本文件;③万字论文文档;④开题报告;⑤答辩PPT;⑥项目运行视频教程。 项目架构: B/S 架构、MVC 分层设计 技术栈: Java、MySQL、SpringBoot、MyBatis-Plus、Token 权限校验、管理后台 Vue+ElementUI+ECharts、用户前台 Layui+jQuery、Maven 构建。 一、角色设计 学生用户: 注册登录、浏览宿舍信息、查询宿舍安排、在线报修、缴费查询、失物招领、桶装水预订、评论交流、收藏等。 商家用户: 注册登录、桶装水品牌与商品信息维护、预订订单查看与处理。 维修人员: 注册登录、查看待处理报修、接单维修、填写报修处理结果与进度反馈。 管理员: 学生管理、班级管理、宿舍信息管理、宿舍安排管理、报修处理管理、缴费信息管理、卫生检查与文明宿舍管理、失物招领管理、桶装水与商家管理、维修人员管理、公告资讯与轮播图管理等。 二、前台功能模块(学生端) 1. 首页展示:轮播图、宿舍公告、最新动态推荐、常用服务快速入口 2. 宿舍信息模块:宿舍列表、楼栋与房间条件筛选、宿舍详情查看、我的宿舍安排查询 3. 在线报修模块:在线提交宿舍设施报修申请、上传故障描述、查看报修进度与维修处理结果 4. 缴费模块:水电等缴费记录查询、缴费状态查看 5. 卫生检查与文明宿舍:宿舍卫生检查结果公示、文明宿舍展示 6. 失物招领模块:失物信息发布、招领信息发布、详情查看、评论互动 7. 桶装水预订:桶装水品牌与商品浏览、在线预订、我的预订记录查询 8. 假期留宿:假期留校申请提交、申请记录查询 9. 评论与收藏:信息评论、查看他人评论、评论回复互动、收藏感兴趣的内容 10. 个人中心... 立即下载

相关推荐

YOLOv8作物病害检测实战源码

这是一套基于YOLOv8n的农田病虫害目标检测系统,对叶片照片做目标检测,识别健康叶片、褐斑病、白粉病、锈病四类,并给出对应防治建议。全流程纯CPU可跑,配套交付完整Python源码、9章实战教程(md/html/pdf三种格式)、100张自造样本及YOLO标签、训练曲线与混淆矩阵截图、Tkinter界面和答辩PPT。 系统围绕五项功能展开:同一套推理逻辑覆盖图像、视频、摄像头三种来源;图形界面选文件即检测,画面叠彩色框标注病名与置信度,右侧面板同步给出症状与防治措施;检测记录自动写入CSV,统计页一键生成四类病害占比饼图;训练结束自动产出损失与精度曲线;内置防治建议文案库,检测命中即回填面板。 选型用YOLOv8n nano档,参数量约320万、权重约6.2MB,CPU单帧几十毫秒,小样本训练5到8分钟完成。数据由data_gen.py程序化绘制100张叶片图,固定随机种子,重跑分布一致,不依赖公开数据集。依赖全部锁版本,教程第7章整理了19条真实报错及排查方法,第8章给出换模型档、换PlantVillage数据集的迁移路径。 适合做计算机视觉方向课程设计或毕业设计的学生,也适合智慧农业方向想了解检测模型如何落进业务面板的学习者。不需要GPU,不需要系统学过目标检测,教程第3章会按需补齐原理。 使用时先pip install -r requirements.txt装好依赖,download_data.py下载预训练权重,data_gen.py生成样本后train.py训练,完成后用main.py infer批量检测或main.py gui启动界面。

浮点数计算务必考虑浮点表示误差并使用epsilon

对于浮点数的计算非常容易产生懒惰的想法而试图忽视掉浮点表示的缺陷。最简单的例子是浮点表示某些数值会有误差,这个时候必须考虑使用epsilon。比如我要比较abs(a/b - c/d)的最小值,如果数值一样就取字典最小序。如下版本是有问题的:double ans = abs(elements[v[0]] * 1.0 / elements[v[1]] - elements[v[2]] * 1.0 / ...

weixin_42325834的博客 2326

数据挖掘实战:决策树 + 聚类 + 关联规则,零 Key 离线可跑(Python 源码)

数据挖掘实战包。用 Python 标准库实现 CART 风格决策树、K-Means 聚类与 Apriori 关联规则,在虚构「星河便利店」会员表和购物篮上跑通分类、分群与购物篮分析,并给出准确率、轮廓系数、支持度/置信度/提升度。零第三方依赖、零 API Key 即可离线跑通。含 4 个样例、离线冒烟、中文 README(含「使用方法」)。均为作者原创可运行源码。MIT。作者 blog.youkuaiyun.com/mtl1994

关于浮点数的EPSILON

如何获取EPSILON的值 在C语言中,float和double的EPSILON值在float.h头文件中以宏的方式给出,分别是 FLT_EPSILON DBL_EPSILON 在C++中,则可以numeric_limits模板类的epsilon方法获取到,分别是 std::numeric_limits<float>::epsilon() std::numeric_lim...

norman_irsa的博客 2万+

产业园区如何高效对接企业技术需求与高校科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

国央企创新负责人如何快速掌握本地科技资源分布与匹配情况?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

一种低效但逻辑简单清晰的Delaunay三角网生成算法

由离散样本点生成Delaunay三角网有多种算法,每个算法的执行效率都不一样,这里介绍一种最简单,最低效,但是算法逻辑最清晰的一种。 Delaunay三角网必须满足的一个条件是任何一个三角形的外接圆都不能包含其他任何一个样本点,因此,本算法通过枚举所有可能的三角形,再经过其外接圆不包含任何其他样本点的判断,如果满足,则记录该三角形,直到所有三角形枚举完毕。 效果图:

分享技术,分享知识 6884

国央企创新负责人如何实现科技成果的精准识别与高效筛选?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

DBL_EPSILON和 FLT_EPSILON的用法

DBL_EPSILON和 FLT_EPSILON主要用于单精度和双精度的比较当中: double a = 0.5; if (a == 0.5) //正确 x++; double b = sin(M_PI / 6.0); if (b == 0.5) //错误 x++; 第一个比较正确,第二个可能正确也可能错误,b==0.5的结果取决于处理器、编译器的版本和设置。比如 Visu

云淡风轻 4万+

高校技术转移办公室人员如何系统化管理科技成果信息?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

刚入职,软件测试岗,有点迷茫不知道下一步怎么提升自己

软件测试前景和发展都是不错,已经入了软件测试这行业就坚挺下去

大白的博客 2218

Camshift的理论与代码解释、DBL_EPSILON和 FLT_EPSILON的用法,反向投影

Camshift原理 camshift利用目标的颜色直方图模型将图像转换为颜色概率分布图,初始化一个搜索窗的大小和位置,并根据上一帧得到的结果自适应调整搜索窗口的位置和大小,从而定位出当前图像中目标的中心位置。 分为三个部分: 1--色彩投影图(反向投影): (1).RGB颜色空间对光照亮度变化较为敏感,为了减少此变化对跟踪效果的影响,首先将图像从RGB空间转换到HSV空间。(2).然

yangdeshun888的博客 2568

DSP TMS320FF28335程序从FLASH中拷贝到RAM中的两种方法及FLASH烧写方法

程序从FLASH中拷贝到RAM中执行的方法 DSP的程序下载执行方式有两种:一种是下载到RAM中在线执行,一种是下载到FLASH中执行。在RAM中执行时,具有执行速度快,可以无限次下载的特点,但是RAM的特点是掉电丢失数据。FLASH具有掉电不丢失数据的特点,但是同时存在执行速度慢和擦写次数有限的缺点。因此综合两者的特点,在DSP的开发过程中一般会结合使用两者。在前期程序调试过程,由于需要频繁的

AEECREN的博客 1万+

在高性能计算中慎用C++ std::complex

 Copyright (c) prototype, all rights reserved。 在不对原文内容(包括作者信息)做任何改动的前提下,欢迎自由转载。 两年多前写的内部资料。现在自己把它翻成中文,贴到我的blog上来。 近来闲暇时,我用C++和表达式模板(expression template)技术实现了一个复数类(注意:是类,而不是类模板)— Complex。

prototype的专栏 1万+

clang-tidy 使用指南

clang-tidy 需要一个编译数据库来了解如何编译你的代码。编译数据库通常是一个名为 compile_commands.json 的文件。在这个示例中,clang-tidy 会对 test.cpp 文件进行分析,并报告任何潜在的问题。例如,它可能会警告 test 函数中的未使用变量 x。clang-tidy 是一个用于 C++ 代码的静态分析工具,可以帮助你发现代码中的潜在问题和改进点。这将在 build 目录中生成一个 compile_commands.json 文件。

weixin_42244181的博客 2362

MATLAB安装

Matlab 2016a 安装包及破解教程百度云分享链接: 链接:https://pan.baidu.com/s/1i6BgD8p       密码:17gg   Matlab安装教程: 1、下载文件,得到R2016a_win64.part1.rar、R2016a_win64.part2.rar两部分安装文件和Matlab 2016a Win64 Crack破解文件。 2、解压安装文件(解...

qq_36734094的博客 17万+

废弃的C++语言特性 - Deprecated C++ features explained

Copyright (c) prototype, all rights reserved。 在不对原文内容(包括作者信息)做任何改动的前提下,欢迎自由转载。0.      必要说明:所谓“废弃”(deprecated, or obsolescent) 的语言特性是指那些在目前的C++标准(ISO/IEC 14882:1998,以下简写为C++98)下仍然是合法的,但在新版标准中很有可能被去除或

prototype的专栏 3658

Vue3项目实战:用vue-print-nb搞定多页表格打印(附样式不丢失解决方案)

本文详细介绍了在Vue3项目中,如何利用vue-print-nb插件解决Element Plus多页表格打印的样式丢失与分页错乱等核心难题。通过分离打印视图、编写专用CSS控制分页行为、以及深入理解浏览器打印原理,提供了一套从基础配置到高级技巧的完整企业级打印解决方案,确保打印输出专业可靠。

linux的博客 1233

C++ Metaprogramming::Typelist::Definitions and basic implementations

Version 1.00Author: prototypeCopyright (C) 2004 prototypePermission is granted to copy and redistribute this article provided that its contents (including the title, author information, and this c

prototype的专栏 2531

上机任务一:空气质量指数 (air quality index,AQI是定量描述空气质量状况的指数。为了更好地了解和人们身体健康息息相关的天气状况,本书模拟生成500条某地区天气数据,一行样本对应一天

调整后的R平方为0.4308,考虑了模型中的自由度,它略低于多重R平方,说明模型的解释能力可能有限。总的来说,新的模型相对于之前的模型在AIC值上更优,包含了最高温度(X2)和最低温度(X3)这两个重要的预测因子,并且对AQI的解释能力较好。在表中,Df表示自由度,Sum Sq表示总平方和,Mean Sq表示均方(总平方和除以自由度),F value表示F统计量,Pr(>F)表示对应的p值。在分析这些结果时,需要关注系数的显著性(p值),系数的方向(正向或负向影响),以及系数的大小(估计值)。

Mrrunsen的博客 723

java项目反编译工具记录,共计6个工具

java项目反编译工具记录,共计6个工具

橙-极纪元-JJYCheng 1801

Design and implement an "Accumulator" class (complete)

  Abstract A few months ago, I wrote two snippets that composed the basics of the initial half of this article. This one is the complete and formal version. Often than not, a seemingly trivi

prototype的专栏 1500

动态SLAM中的YOLO与ORB-SLAM3融合:实时目标检测与动态点云滤除实战

本文介绍了如何结合YOLOv5目标检测与ORB-SLAM3视觉SLAM系统,实现动态环境下的目标检测与视觉SLAM任务。文章详细阐述了从源码下载、依赖安装(包括libtorch配置)、编译运行步骤(包括ROS环境和非ROS环境下的编译方法),到RGBD-TUM数据集准备与关联处理的全流程。同时针对常见错误提供了解决方案,如libtorch路径配置、ROS环境冲突等。最后展示了系统运行方法,并探讨了未来可能的优化方向,包括增强目标检测能力和改进动态环境下的地图构建。该集成系统为机器人智能导航和环境感知提供了有

LXY_LOVE36的博客 237

My "C++ Metaprogramming::..." is infinitely postponed.

Just for making a mark.I will come back when I have time for this.I will work on this blog by putting up some stuff that is less time-consuming. :-)

prototype的专栏 1375

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: Loop, data, and MapReduce
prototype
博客等级 码龄25年 9粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值