Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom precision in error reports for floating-point numbers #1612

Closed
mlimber opened this issue Apr 26, 2019 · 2 comments · Fixed by #1614
Closed

Allow custom precision in error reports for floating-point numbers #1612

mlimber opened this issue Apr 26, 2019 · 2 comments · Fixed by #1614

Comments

@mlimber
Copy link
Contributor

mlimber commented Apr 26, 2019

Description
As in this SO Q&A, it would be nice to allow customization of the precision of floating-point values that fail. At present, the precision for float and double are hard-coded within Catch2 to 5 and 10, respectively:

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

Sometimes things will fail (even with Approx()), but the precision of the failure message doesn't show enough precision to be meaningful.

prog.cc:22: FAILED:
  REQUIRE( TestType(0) == std::numeric_limits<TestType>::epsilon() )
with expansion:
  0.0f == 0.0f

The proposal here is to add a setPrecision() function to allow the user to control this. I have prototyped this, which you can see running live on Wandbox. Here's the test:

TEMPLATE_TEST_CASE( "Double, double, toil and trouble", "[double]", float, double ) 
{
    const auto precision = GENERATE( -1, 0, 3, std::numeric_limits<TestType>::max_digits10 );

    if( precision >= 0 )
    {
        Catch::StringMaker<TestType>::setPrecision( precision );
    }
    
    // Expected to fail to demonstrate the problem
    REQUIRE( TestType(0) == std::numeric_limits<TestType>::epsilon() ); 
}

The output shows as expected for floats and doubles. For instance:

prog.cc:15: FAILED:
  REQUIRE( TestType(0) == std::numeric_limits<TestType>::epsilon() )
with expansion:
  0.0f == 0.000000119f

Making a unit test for this is a little iffy since the actual string values are dependent on the usual floating-point fuzziness. I guess it could compare string length without looking too closely at the value.

@ecorm
Copy link

ecorm commented Jun 15, 2020

Is Catch::StringMaker<T>::setPrecision sticky, or does it only affect the current test case?

@horenmar
Copy link
Member

It is sticky. For ease of implementation, it is a type-level static.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants