C++面试题(3)------如何判断两个小数是否相等

  • 操作系统: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()✅ 推荐高精度要求、跨平台代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村北头的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值