Skip to content

浮点数比较问题

今天做题的时候,看到一道题,有点懵,题目是:

写出float x 与“零值”比较的if语句

第一反应,嗯?啥意思?比较浮点数和0的大小么?不确定,于是百度了一下:

C语言:

const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
//不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。

如果执行下面的代码:

#include<stdio.h>
int main(){
    float a = 0.0;
    if(a == 0){
        printf("a=0"\n");
    }
}

毫无疑问会输出:a=0

那为什么说浮点数之间的比较不能用==和!=呢?

下面看看若直接用==判断两个浮点数的大小会出现什么情况:

 

#include<stdio.h>
#include<float.h>
#include<math.h>

int main(){
    float a = 3252.88;
    float b = 3252.0;
    float c = 0.88;

    float tmp = a - b;
    if(tmp > c){
        printf(">%f\n", tmp, c);
    }else if(tmp < c){
        printf("<%f\n", tmp, c);
    }else{
        printf("=%f\n", tmp, c);
    }
}

输出:<0.880000

为啥?看看tmp的值:0.879883,并不等于0.88。

这就是一个精度问题了,计算机处理浮点数的时候是有误差的,所以判断两个浮点数是否相等,应该判断它们的差是否落在一个区间,这个区间就是   [-EPSINON,EPSINON] ,  EPSINON很小,一般为1e-6以下,应根据具体问题确定精度。

这里tmp和c的差是0.000117,所以这两者之差在[-0.001,0.001]之间,于是只需确保精度为0.001就可以得到相等的结果:

#include<stdio.h>
#include<float.h>
#include<math.h>

# define ESP 1e-3  //定义常量
int main(){
    float a = 3252.88;
    float b = 3252.0;
    float c = 0.88;

    float tmp = a - b;

    if(fabs(tmp - c) <= ESP){
        printf("%f=%f\n", tmp, c);
    }else if(tmp > c && fabs(tmp - c) > ESP){
        printf("%f>%f\n", tmp, c);
    }else{
        printf("%f<%f\n", tmp, c);
    }
}

输出:0.879883=0.880000

fabs是求浮点数绝对值的函数,类似地:

当判断大于的时候,使用if(a>b && fabs(a-b)>1e-6)。

当判断小于的时候,使用if(a<b&&fabs(a-b)>1e-6)。

 

 

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注