在c语言中有很多数据类型,如int,char,float, double等,每个类型在使用时都要涉及到比较运算,我们都知道int这样的数据进行比较时常常用到“==”来判断是否相等,但是浮点类型却不能通过“==”来判断是否相等,这是为什么呢?
我们来看一段代码:
int main()
{
double x = 0.1;
printf("%lf", x);
return 0;
}
运行结果如下:
我们发现,0.1如实的被打印了出来
但我们再看看接下来这段代码:
int main()
{
double x = 0.1;
printf("%.50f", x);
return 0;
}
这段代码与上面的区别在于我们将x的小数点后50位都打印出来,来看看结果:
这可能出乎你的意料,为什么 后面不都是0呢,其实是因为浮点型数据在进行存储的时候会发生精度丢失,这样就无法按照常规思想进行“相等比较”,我们举个例子:
int main()
{
double x = 1.0;
double y = 0.1;
if (y == x - 0.9)
{
printf("=\n");
}
else
{
printf("??\n");
}
}
按照正常的想法x-0.9应该为0.1,打印出来因该是“=”才对,为什莫会这样呢,我们试着将上面的值打印下来:
int main()
{
double x = 1.0;
double y = 0.1;
printf("%.50f", x - 0.9);
printf("%.50f", y);
return 0;
}
我们发现他们即使相差很小,但他们的数值是不相等的,正是因为浮点数运算会产生精度丢失,我们不应使用“==”进行两个浮点数的相等比较。
浮点数相等比较方式 :利用精度
从上面我们发现两个浮点数很难完全相等,但是他们十分接近,所以我们需要引进精度来判断两数之差的绝对值是否小于精度,来近似判断相等 。
int main()
{
double x = 1.0;
double y = 0.1;
if (fabs((x - 0.9) - 0.1) < 1e-6)//设置精度为10的-6次方
{
printf("=\n");
}
else
{
printf("???\n");
}
return 0;
}
我们自己设立了一个精度来进行相等判断
我们得到了想要的结果。
但是又有一个问题,精度该怎样控制呢?如果精度控制不好的话,会不会影响结果呢,为了解决这个问题,我们需要介绍两个值DBL_EPSILON和FLT_EPSILON
其实这是两个c语言库函数float.h里面定义的宏
这是其头文件的内容:FLT_EPSILON是进行double型数据比较时的精度
DBL_EPSILON是进行double型数据比较时的精度
后面的英文意思是,某个值加上一个数会与原来不同,而这个值是使数发生变化的最小值,那么一个数加上比它还小的数,我们仍为值不变!
所以我们利用这个值来更改代码:
#include<float.h>
#include<math.h>
int main()
{
double x = 1.0;
double y = 0.1;
//判断时注意不应为 <= 原因请看上面库里的英文和我的解释
if (fabs((x - 0.9) - 0.1) < DBL_EPSILON)
{
printf("=\n");
}
else
{
printf("???\n");
}
return 0;
}
我们成功的得到了想要的结果。
分享就到这儿啦。