Catch2 中对浮点数进行比较
在 Catch2 中对浮点数进行比较
在 Catch2 测试框架中,对浮点数进行比较需要使用专门的浮点比较宏,因为直接使用 ==
比较浮点数可能会由于精度问题导致测试失败。以下是 Catch2 中浮点数比较的方法:
基本浮点比较
#include <catch2/catch.hpp>
TEST_CASE("Floating point comparisons") {
double a = 0.1 + 0.2;
// 近似相等比较
REQUIRE(a == Approx(0.3));
// 也可以这样写
REQUIRE(a == 0.3_a); // C++14 用户定义字面量语法
}
高级浮点比较选项
TEST_CASE("Advanced floating point comparisons") {
double x = 1.23456;
// 设置相对误差容限
REQUIRE(x == Approx(1.23).epsilon(0.01));
// 设置绝对误差容限(当值接近0时有用)
REQUIRE(x == Approx(1.23).margin(0.01));
// 同时设置相对和绝对容限
REQUIRE(x == Approx(1.23).epsilon(0.01).margin(0.001));
// 设置比例因子(默认1.0)
REQUIRE(x == Approx(1.23).scale(100.0));
}
比较两个浮点数的相对误差
TEST_CASE("Relative error comparison") {
double computed = 100.0;
double expected = 101.0;
// 允许1%的相对误差
REQUIRE(computed == Approx(expected).epsilon(0.01));
}
注意事项
Approx
默认的 epsilon 值是std::numeric_limits<float>::epsilon()*100
- 比较时会同时考虑相对误差和绝对误差
- 对于接近0的值,相对误差比较可能不适用,此时应使用
margin
设置绝对误差容限 - Catch2 v3.x 版本中这些功能仍然可用,但语法可能略有不同
Catch2 v3.x 中的浮点比较
在 Catch2 v3.x 中,语法基本保持一致:
#include <catch2/catch_all.hpp>
TEST_CASE("Floating point in Catch2 v3") {
double a = 0.1 + 0.2;
REQUIRE_THAT(a, Catch::Matchers::WithinRel(0.3));
// 或
REQUIRE(a == Catch::Approx(0.3));
}
使用这些专门的浮点比较方法可以避免由于浮点精度问题导致的测试失败,使测试更加健壮。