- 操作系统:ubuntu22.04
- IDE:Visual Studio Code
- 编程语言:C++11
在 C++ 中,直接使用 == 来判断两个浮点数(如 float 或 double)是否相等是不安全的,因为浮点运算存在精度损失和舍入误差。
为什么不能直接用 ==?
浮点数在计算机中是以二进制近似表示的,很多十进制小数无法精确表示为有限长度的二进制小数。例如:
double a = 0.1 + 0.2;
double b = 0.3;
if (a == b) {
cout << "相等"; // 实际不会进入这个分支!
} else {
cout << "不相等"; // 实际输出这个
}
这是因为:
- 0.1 和 0.2 在二进制下是无限循环的;
- 计算机只能存储近似值;
- 所以 a 和 b 的实际值会有微小差异。
正确做法:判断两个浮点数是否“足够接近”
我们通常使用一个很小的正数 ε(epsilon)来判断两个浮点数的差是否小于这个值。
方法一:使用固定误差范围(适合简单场景)
#include <iostream>
#include <cmath> // 用于 fabs
using namespace std;
const double EPS = 1e-8; // 定义一个极小误差值
bool isEqual(double a, double b) {
return fabs(a - b) < EPS;
}
int main() {
double a = 0.1 + 0.2;
double b = 0.3;
if (isEqual(a, b)) {
cout << "相等" << endl;
} else {
cout << "不相等" << endl;
}
return 0;
}
输出:
相等
方法二:相对误差判断(更适用于大数比较)
当处理非常大的浮点数时,可以使用相对误差判断两个数是否相等:
bool isEqual(double a, double b) {
if (a == b) return true;
double diff = fabs(a - b);
a = fabs(a);
b = fabs(b);
double maxVal = (a > b) ? a : b;
return diff <= EPS * maxVal;
}
这能避免绝对误差对大数不敏感的问题。
方法三:结合 std::numeric_limits(C++ 标准库推荐)
如果你希望更专业地处理浮点数比较,可以使用 头文件中的 std::numeric_limits:
#include <iostream>
#include <cmath>
#include <limits>
using namespace std;
bool isEqual(double a, double b) {
double diff = fabs(a - b);
double epsilon = numeric_limits<double>::epsilon();
return diff <= epsilon * max(fabs(a), fabs(b));
}
int main() {
double a = 0.1 + 0.2;
double b = 0.3;
if (isEqual(a, b)) {
cout << "相等" << endl;
} else {
cout << "不相等" << endl;
}
return 0;
}
总结对比
方法 | 是否推荐 | 场景 |
---|---|---|
直接 == | ❌ 不推荐 | 永远不要用 |
固定误差(EPS = 1e-8) | ✅ 推荐 | 简单应用、算法题 |
相对误差判断 | ✅ 推荐 | 工程计算、科学计算 |
numeric_limits::epsilon() | ✅ 推荐 | 高精度要求、跨平台代码 |