判断相等

在 C 语言中,不能直接用 == 来判断两个浮点数是否相等,浮点数在内存中是以二进制形式存储的,存在精度误差。

例如:

#include <stdio.h>

int main() {
    float a = 0.1;
    float b = 0.2;
    float c = 0.3;

    if (a + b == c) {
        printf("相等\n");
    } else {
        printf("不相等\n");
    }

    return 0;
}

输出是不相等,因为 0.1 和 0.2 在二进制中是无限循环小数,相加后和 0.3 有微小差别。

正确的方法:比较差值是否小于一个很小的数

我们通常定义一个极小的误差范围(epsilon),当两个数的差的绝对值小于这个范围时,就认为它们相等。

#include <stdio.h>
#include <math.h> // 需要包含 math.h 才能使用 fabs

#define EPS 1e-6 // 定义一个足够小的误差范围

int main() {
    float a = 0.1;
    float b = 0.2;
    float c = 0.3;

    if (fabs((a + b) - c) < EPS) {
        printf("相等\n");
    } else {
        printf("不相等\n");
    }

    return 0;
}

注意事项

  1. EPS 的选择:根据你的精度需求选择合适的 epsilon 值,1e-6float 足够,1e-91e-12double 更合适。
  2. 使用 fabs()fabs() 用于取浮点数的绝对值,需要包含 <math.h>
  3. 避免比较接近零的数:当比较接近零的数时,可能需要使用相对误差比较。

更精确的方法(相对误差)

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

#define EPS 1e-9

int main() {
    double a = 1.23456789012345;
    double b = 1.23456789012346;

    if (fabs(a - b) / (fabs(a) + fabs(b)) < EPS) {
        printf("相等\n");
    } else {
        printf("不相等\n");
    }

    return 0;
}

这种方法对于比较非常大或非常小的数更可靠。

判断浮点数是否小于某个值

在 C 语言中,判断一个浮点数是否小于某个值可以直接用 < 运算符,这不会像 == 那样有严重的精度问题。

直接比较

#include <stdio.h>

int main() {
    double x = 1.23456789;
    double limit = 2.0;

    if (x < limit) {
        printf("x 小于 limit\n");
    } else {
        printf("x 不小于 limit\n");
    }

    return 0;
}

注意事项

  1. 精度问题:如果你的浮点数是通过计算得到的,可能会有微小误差,但这对 < 比较影响不大。

  2. 边界情况:如果需要判断 “小于等于”,可以使用 <= 运算符。

  3. 特殊值

    • 浮点数可能是 NaN(Not a Number),任何与 NaN 的比较都返回假
    • 可以用 isnan() 函数检查(需要 #include <math.h>

处理精度问题的方法

如果担心计算误差导致边界判断不准确,可以使用一个小的容差(epsilon):

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

#define EPS 1e-9

int main() {
    double x = 2.0000000001;
    double limit = 2.0;

    // 判断 x 是否小于等于 limit(考虑精度误差)
    if (x < limit + EPS) {
        printf("x 小于等于 limit\n");
    } else {
        printf("x 大于 limit\n");
    }

    return 0;
}