由于计算机中采用有限位的二进制编码,因此浮点数在计算机中的存储并不总是精确的。例如在经过大量的运算后,一个浮点型数3.14就有可能变成3.1400000000001,也有可能变成3.1399999999999,这种情况下会对比较操作带来极大的困扰(因为 "==" 操作是完全相同时才能判定为 true). 于是需要引入一个极小数 eps 来对这种误差进行修正。
一 等于运算符
由于浮点数比较时有误差,所以如果一个数 a 落入[b-eps,b+eps]的区间中间,就应当判定a==b成立,经验表明:eps取1e-8是一个比较合适的数字——对大多数的情况既不会漏判,也不会误判,因此可以将eps定义成常量1e-8;
const double eps=1e-8;
为使比较更加方便,把比较操作写成宏定义的形式:
#define Equ(a,b) ((fabs((a)-(b)))<(eps))
二 大于运算符(>)
如果一个数 a 要大于 b ,那么必须在误差 eps 的扰动范围外大于b ,因此只有大于 b+eps 的数才能判定为大于 b (也即a-b>eps)
#define More(a,b) (((a)-(b))>(eps))
三 小于运算符(<)
如果一个数 a 要小于 b ,那么必须在误差 eps 的扰动范围外小于b ,因此只有小于 b-eps 的数才能判定为小于 b (也即a-b<-eps)
#define Less(a,b) (((a)-(b))<(-eps))
四 大于等于运算符(>=)
由于大于等于运算符可以理解为大于运算符和等于运算符的结合,于是让一个数 a 在误差扰动范围内能够判定其大于或者等于b,因此大于 b-eps 的数都应判定为大于等于b(也即a-b>-eps)
#define MoreEqu(a,b) (((a)-(b))>(-eps))
五 小于等于运算符
由于小于等于运算符可以理解为小于运算符和等于运算符的结合,于是让一个数 a 在误差扰动范围内能够判定其小于或者等于b,因此小于 b+eps 的数都应判定为小于等于b(也即a-b<eps)
#define LessEqu(a,b) (((a)-(b))<(eps))
六 圆周率 pi
由于 cos(pi)=-1; 可知:pi=arccos(-1.0);
因此 const double PI=arccos(-1.0);
把上面的核心汇总起来就是下面这些代码:
const double PI=arccos(-1.0);
const double eps=1e-8;
#define Equ(a,b) ((fabs((a)-(b)))<(eps)) ///等于
#define More(a,b) (((a)-(b))>(eps)) ///大于
#define Less(a,b) (((a)-(b))<(-eps)) ///小于
#define MoreEqu(a,b) (((a)-(b))>(-eps)) ///大于等于
#define LessEqu(a,b) (((a)-(b))<(eps)) ///小于等于