更新:您
现在可以 在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:在更高精度下自行记录日志
如果在REQUIRE()
调用之前添加INFO( FullPrecision(d) );
,则仅在测试用例失败时才会获得完整精度的打印输出。(请参见下面FullPrecision()
的定义。)
这两个更改在此处演示:
#define CATCH_CONFIG_MAIN
#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上实时查看。
Approx
,请展示它。否则,人们可能会抱怨您在浮点值之间使用直接比较的方式是有缺陷的。整个[mcve]的重点应该是展示您的问题,并且不引入其他无关的问题。 - Some programmer dudesomeFunc() { return 0;}
将通过测试,但在某些奇怪的边角情况下,使用==
可能是可以的,因此这个问题是合理的(当然,我同意给出不使用==
的提示)。 - 463035818_is_not_a_number15.000000000001 < 15
,输出是否会产生相同的效果?也许您可以完全避免浮点数==
问题,并仍然得出相同的解决方案。 - 463035818_is_not_a_number