写代码时,经常会遇到判断两个数字是否相等的场景。比如做价格计算、传感器数据比对、或者用户输入验证。可一旦这两个数字是浮点数,比如 0.1 + 0.2 和 0.3,你会发现它们居然不相等。
这不是你的错,也不是程序出了 bug,而是浮点数在计算机里的表示方式天生就有精度误差。IEEE 754 标准下,大多数小数无法被二进制精确表示,就像十进制里除不尽的 1/3 一样。
直接用 == 比较浮点数?危险!
来看一个经典例子:
double a = 0.1 + 0.2;
结果会输出“不相等”。因为 a 实际上是 0.30000000000000004,而 b 是 0.3,差了一丁点,但就是不相等。
那该怎么安全地比较?用误差范围
正确的做法是:不要求完全相等,而是判断两个数的差值是否足够小。这个“足够小”的值,叫做容差(epsilon)。
比如这样写:
#include <math.h>
#define EPSILON 1e-9
int float_equal(double a, double b) {
return fabs(a - b) < EPSILON;
}
然后你就可以用 float_equal(0.1 + 0.2, 0.3) 来判断它们“基本相等”了。只要差距小于十亿分之一,就认为是一样的。
这个 EPSILON 不是固定值,得看你的业务场景。如果是金融计算,可能要更严格,比如 1e-12;如果是温度传感器读数,差个 0.01 都能接受,那设成 1e-2 也行。
相对误差更稳妥
上面的方法叫绝对误差,适用于数值范围比较小的情况。但如果两个数本身很大,比如都是上百万,那即使差个几万,相对比例也不大。这时候应该用相对误差。
int float_equal_relative(double a, double b) {
double max_ab = fmax(fabs(a), fabs(b));
return fabs(a - b) < EPSILON * max_ab;
}
这样能适应不同数量级的数据,避免在大数比较时误判。
实际开发中,很多语言也提供了现成方案。比如 Python 的 math.isclose(),Java 的 Double.compare() 配合阈值,C++ 可以用 std::abs 加判断。
总之,浮点数比较不是简单的“等于”问题,而是“差不多就行”的工程判断。尤其是在涉及金额、安全控制、自动化决策的系统里,一个错误的比较可能导致资金损失或设备误动作。别图省事用 ==,加个容差,心里才踏实。