Opened 5 years ago

Closed 5 years ago

#13011 closed Bugs (fixed)

BOOST_TEST broken with floating point relational operators

Reported by: chris42f@… Owned by: Raffi Enficiaud
Milestone: Boost 1.65.0 Component: test
Version: Boost 1.63.0 Severity: Regression
Keywords: Cc:

Description

This is one of those crazy "Surely I must be doing something wrong here" things. But as far as I can tell, floating point comparisons don't work at all with the bare BOOST_TEST macro. A minimal reproduction


#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>

BOOST_AUTO_TEST_CASE(Foo)
{
    BOOST_TEST(0.0 < 1.0);
}

Compiler:

$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.

Change History (9)

comment:1 by nigels.com@…, 5 years ago

Seems be due to BOOST_TEST handling of floating point comparison.

http://www.boost.org/doc/libs/1_64_0/libs/test/doc/html/boost_test/testing_tools/extended_comparison/floating_point/floating_points_comparison_theory.html

This passes, for example:

#define BOOST_TEST_MODULE test
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_CASE(Foo)
{
    BOOST_TEST(0.001 < 0.002);
}

comment:2 by chris42f@…, 5 years ago

Right, thanks for digging. Honestly I didn't expect floating point comparison magic in BOOST_TEST by default, and was expecting to do my own epsilon testing.

It's unfortunate that the default behavior fails some obvious desired properties at 0.0 - which as the additive identity is arguably the most commonly encountered value out of the entire floating point range.

I'll admit that in the real use case, I was trying to do my own epsilon testing with a known absolute tolerance specific to the problem - something like

BOOST_TEST(fabs(a-b) < 1e-16)

which fails when a happens to be equal to b. Overall, I'm not thrilled that boost tries to completely hide the problems of floating point comparison from users.

For this case, it sounds like a solution with the current API is to use the obviously naive expression

BOOST_TEST(a == b)

comment:3 by nigels.com@…, 5 years ago

Yes, I agree that the principle of least-surprise ought to apply to BOOST_TEST.

Perhaps we ought to cast to bool as a matter of best practice.

BOOST_TEST( bool(fabs(a-b) < 1e-16) )

comment:4 by anonymous, 5 years ago

Using the bool cast as a matter of course would be terribly unfortunate as it defeats the automatic expression splitting and enhanced error reporting, which is really the whole point of the new BOOST_TEST interface.

comment:5 by nigels.com@…, 5 years ago

My opinion is that the tolerancing built into BOOST_TEST ought to be opt-in.

I'll give it another look the next time I'm adding unit testing, but my initial impression is that I'd rather be explicit about epsilon testing, and be a bit less concerned about the precise type to use for the tolerance value. (Ordinarily I'd expect the usual type promotion rules to apply)

comment:6 by Raffi Enficiaud, 5 years ago

Owner: changed from Gennadiy Rozental to Raffi Enficiaud
Status: newassigned

comment:7 by Raffi Enficiaud, 5 years ago

Milestone: To Be DeterminedBoost 1.65.0

comment:8 by Raffi Enficiaud, 5 years ago

Fixed in topic/13011-floating-point-relational-operators

comment:9 by Raffi Enficiaud, 5 years ago

Resolution: fixed
Status: assignedclosed

In master, rev 3ddb0e0d29e8ebfe4ba20921a3d366f7b5b837b2

Note: See TracTickets for help on using tickets.