使用Catch比较双精度向量

5
我正在使用Catch单元测试框架,并希望比较一组双精度浮点数。这个其他答案建议使用Approx来比较浮点/双精度值,但是这对于它们的向量并不起作用。有没有方便的方法来完成这个任务?
编辑:一个例子
使用以下代码:
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

TEST_CASE("Compare Vectors", "[vector]") {
    std::vector<int> vec1 = {0, 1, 2, 3};
    std::vector<int> vec2 = {0, 1, 2, 4};
    REQUIRE(vec1 == vec2);
}

测试失败,报告如下:
-------------------------------------------------------------------------------
Compare Vectors
-------------------------------------------------------------------------------
test/UnitTests/test_Example/example.cc:4
...............................................................................

test/UnitTests/test_Example/example.cc:7: FAILED:
  REQUIRE( vec1 == vec2 )
with expansion:
  { 0, 1, 2, 3 } == { 0, 1, 2, 4 }

===============================================================================
test cases: 1 | 1 failed
assertions: 1 | 1 failed

但是如果我将代码更改如下,我希望测试能够通过,但显然它没有。

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

TEST_CASE("Compare Vectors", "[vector]") {
    std::vector<double> vec1 = {0, 1, 2, 3};
    std::vector<double> vec2 = {0, 1, 2, 3.000001};
    REQUIRE(vec1 == vec2);
}

我可以循环遍历这些元素并逐一比较,但是如果出现差异,确定错误来源将更加困难。


1
循环遍历向量并逐个比较怎么样?还可以参考这个问题 - vsoftco
@vso 我认为问题不在于如何循环遍历向量,而是在这样做时如何比较浮点数。 - user2100815
2个回答

5

虽然自Catch 2.7.2以来已经过去了约4年,但现在用户可以使用Approx比较向量:

REQUIRE_THAT(vec1, Catch::Approx(vec2).margin(0.0001));

比较两个向量的误差在+-0.0001之内。

更多信息请参见此处


2

目前我已经采用了一种解决方法。我创建了以下两个函数,可以在需要检查两个向量的地方使用。(例如REQUIRE(compareVectors(vec1, vec2));)

bool compareVectors(std::vector<double> a, std::vector<double> b) {
    if (a.size() != b.size()) return false;
    for (size_t i = 0; i < a.size(); i++) {
        if (a[i] != Approx(b[i])) {
            std::cout << a[i] << " Should == " << b[i] << std::endl;
            return false;
        }
    }
    return true;
}

bool compare2dVectors(std::vector<std::vector<double>> a,
                      std::vector<std::vector<double>> b) {
    if (a.size() != b.size()) return false;
    for (size_t i = 0; i < a.size(); i++) {
        if (! compareVectors(a[i], b[i])) return false;
    }
    return true;
}

这样,您至少可以看到失败的向量名称以及第一个不同的值。

这并不是最理想的解决方案,所以我仍然希望有人能提出更好的方法,但我想至少分享一下我迄今为止想到的内容,以防对某些人有所帮助。


1
我也遇到了同样的问题,我对更优雅的解决方案很感兴趣。 - schorsch312

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接