使用Catch2以全精度打印浮点值

时间:2019-04-26 12:22:43

标签: c++ unit-testing catch2

我有一些使用的测试代码,它确实检查了某些计算是否返回浮点空值。

CHECK( someFunc() == 0. );

问题是当由于非常小的非空值(例如1.234E-16)而导致测试失败时,这些值将以“默认”打印方式打印,我看到:

my_test.cpp:351: FAILED:
  CHECK( someFunc() == 0.0 )
with expansion:
  0.0 == 0.0

这几乎没有用。我想看的是:

my_test.cpp:351: FAILED:
  CHECK( someFunc() == 0.0 )
with expansion:
  1.234E-16 == 0.0

我在测试之前尝试在std::scientific中流std::cout的流,但是显然是使用另一种打印方法捕获的。

有什么想法吗?

旁注:实际上,我使用提供的Approx类,但这与我的问题无关

编辑:这里的问题不是比较本身(我知道有关浮点值的所有弊端),不是,只是 strong>关于如何告诉Catch打印已处理的值。

1 个答案:

答案 0 :(得分:3)

更新 :您can now specify precision in Catch2。以下适用于旧版本的Catch2。

看起来精度是在Catch2本身中硬编码的:

std::string StringMaker<float>::convert(float value) {
    return fpToString(value, 5) + 'f';
}
std::string StringMaker<double>::convert(double value) {
    return fpToString(value, 10);
}

有两种方法可以解决此问题:

选项1:修改Catch2

如果对此进行了修改,则可以使其显示所需的内容(注意:<limits>已包含在catch中,因此我将使用std::numeric_limits):

std::string StringMaker<float>::convert(float value) {
    return fpToString(value, std::numeric_limits<float>::max_digits10) + 'f';
}
std::string StringMaker<double>::convert(double value) {
    return fpToString(value, std::numeric_limits<double>::max_digits10);
}

可以采用一种更复杂的方法,使它成为用户可以设置的参数,而不是将其硬编码为其他半任意值,但这只是一个问答,而不是请求请求。 ;-)

选项2:以更高的精度自己记录

如果在INFO( FullPrecision(d) );调用之前添加REQUIRE(),则只有在测试用例失败时,您才能获得全精度打印。 (请参见下面的FullPrecision()的定义。)

这两个更改均在此处演示:

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include <limits>
#include <sstream>
#include <iomanip>

double GetDouble() { return std::numeric_limits<double>::epsilon(); }

std::string FullPrecision( double d )
{
    auto s = std::ostringstream{};
    s << std::setprecision( std::numeric_limits<double>::max_digits10 ) << d;
    return s.str();
}

TEST_CASE( "Double, double, toil and trouble", "[double]" ) 
{
    const auto d = GetDouble();
    INFO( FullPrecision(d) );
    REQUIRE( 0.0 == d );
}

打印:

prog.cc:20: FAILED:
  REQUIRE( 0.0 == d )
with expansion:
  0.0 == 0.00000000000000022
with message:
  2.2204460492503131e-16

修改Catch2导致扩展0.0 == 0.00000000000000022,添加INFO()导致消息2.2204460492503131e-16

Wandbox 上实时观看。