浮点数的比较困扰了我很久,今天终于看到了解决办法在此分享一下。
因为计算机采用有限二进制数编码,所以浮点数在计算机中的存储总是不精确的。在大量计算后一个浮点数1.18可能在计算机中就会变为1.18000000000001或者1.17999999999999,在这种情况下c/c++使用“==”操作必须是完全相同才能是true,因此必须引入一个最小量eps作为修正。经验表明eps一般取10-8。
所以我们写程序的时候就可以这样:
const double eps = 1e-8; #define Equ(a,b) ((abs((a)-(b)))<(eps))
举个例子:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; const double eps = 1e-8; #define Equ(a,b) ((fabs((b)-(a)))<(eps)) int main(){ double a = 1.23; if(Equ(a,1.23)){ printf("T"); }else{ return 0; } }
特别说一下大于等于的做法。
设一个浮点数 a ∈(a-eps,a+eps)那么另一个浮点数b要大于等于a,则b>a-eps,所以b-a>-eps。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const double eps = 1e-8; 6 #define MoreEqu(a,b) ((fabs((b)-(a)))>(-eps)) 7 int main(){ 8 double a = 1.23; 9 if(MoreEqu(a,1.23)){ 10 printf("T"); 11 }else{ 12 return 0; 13 } 14 }
再说一个关于圆周率的表示。
因为cosπ = -1,所以π = arccos-1
const double pi = acos(-1.0);
最后有一点要注意,经过了大量的运算0.00可能是一个负数即-0.00,这时要是使用sqrt()函数就会出错,这时就要加上一个eps保证你要运算的数在定义域内。同样的问题也适用于arcsin(+1)和arcsin(-1)等函数里。