浮点数的比较

本文探讨了计算机中浮点数比较的不精确性,并介绍了如何通过误差修正来判断浮点数相等、大于、小于、大于等于和小于等于。通过设置一个极小量eps(如1e-8),并使用宏定义实现比较操作,确保在精度范围内正确判断浮点数的关系。
摘要由CSDN通过智能技术生成

前些天刷题的时候,碰到了关于浮点数比较的一些细节问题,所以我重温了一下算法笔记中的相关介绍(2.9.2节有兴趣的同学可以自己去看一下这本书),借此写下了这篇博客

浮点数的比较

由于计算机中采用有限位的二进制编码,因此浮点数在计算机中的存储并不总是精确的。例如:在经过大量计算后,一个浮点型的数3.14在计算机中就可能存储成3.140000000.1,或者3.1399999999,等等,这种情况下会对比较操作造成极大的干扰,== 就不对了(在C/C++中“==”要完全相同才是true)。所以我们需要引入一个极小的数eps来对这种误差进行修正。

1. 等于(==)

在这里插入图片描述
等于区间示意图

只要a落在了[b-eps, b+eps]这个区间之间,就可以判断a与b相等(即a==b成立);
根据经验,eps取10^-8是一个合适的数字,对于大多数情况既不会漏判也不会误判;
cosnt double eps = 1e-8;
  • 用宏定义来写比较操作
#define Equ(a, b) ((fabs((a)-(b))) < (eps))
  • 如上,将a与b相减,若差的绝对值小于极小量eps,则返回true;
  • 加上这么多的括号,是为了防止宏定义可能带来的错误;
  • 想使用不等于,直接在Equ函数前加一个! 即可;

2. 大于(>)


大于区间示意图

如果a要大于b,那么就必须在误差eps的波动范围之外大于b,因此只有大于b+eps的数才能判定为
大于b(即a减b大于eps)
  • 用宏定义来写大于函数如下:
#define More(a, b) (((a)-(b)) > (eps))

3. 小于(<)

在这里插入图片描述
小于区间示意图

如果a要小于b,那么就必须在误差eps的波动范围之外小于b,即只有小于b-eps的数才可以判定为
小于b(即a减b小于-eps)
  • 用宏定义描述函数如下:
#define Less(a, b) (((a) - (b)) < (-eps))

4. 大于等于(>=)

在这里插入图片描述
大于等于区间示意图

可以将大于等于运算符,理解为大于和等于的结合,所以要判定a大于等于b,就要让a在误差波动范
围内能判定其大于或者等于b,即大于b-eps的数都可以判定为大于等于b
  • 用宏定义表示函数如下:
#define MoreEqu(a, b) (((a) - (b)) > (-eps))

5. 小于等于(<=)

在这里插入图片描述
小于等于区间示意图

与大于等于同理,考虑误差波动范围,小于b + eps的数都可以判定为小于等于b
  • 用宏定义表示函数如下:
#define LessEqu(a, b) (((a) - (b)) < (eps))

6. 附加一个圆周率π

const double Pi = acos(-1.0); // 因为cos(π) = -1;
  • 坑:还有一些细节,后续会再补充
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑师傅炒板栗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值