【问题标题】:Compare Vector of Doubles Using Catch使用 Catch 比较双精度向量
【发布时间】:2017-01-25 23:21:08
【问题描述】:

我正在使用Catch 单元测试框架,我想比较一个双精度向量。这个other answer 建议使用 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);
}

我可以遍历元素并逐一比较它们,但如果出现差异,将更难以确定错误的来源。

【问题讨论】:

  • 遍历向量并逐元素比较怎么样?另见this question
  • @vso 我认为问题不在于如何遍历向量,而是如何在这样做的同时比较浮点数。

标签: c++ unit-testing catch-unit-test


【解决方案1】:

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

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

这将比较两个向量在误差 +- 0.0001 以内。 更多详情here.

【讨论】:

    【解决方案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;
    }
    

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

    这不是理想的解决方案,所以我仍然希望有人能够想出更好的东西,但我想我至少会分享一下我到目前为止的想法,以防它对某人有所帮助。

    【讨论】:

    • 我面临着同样的问题,我对更优雅的解决方案很感兴趣。
    猜你喜欢
    • 2018-06-05
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 2020-12-02
    • 2023-03-11
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多