#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:


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

#include <boost/test/auto_unit_test.hpp>

    BOOST_TEST(0.0 < 1.0);


$ 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 Changed 20 months ago by nigels.com@…

Seems be due to BOOST_TEST handling of floating point comparison.


This passes, for example:

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

    BOOST_TEST(0.001 < 0.002);

comment:2 Changed 20 months ago by chris42f@…

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 Changed 20 months ago by nigels.com@…

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 Changed 20 months ago by anonymous

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 Changed 20 months ago by nigels.com@…

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 Changed 19 months ago by Raffi Enficiaud

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

comment:7 Changed 18 months ago by Raffi Enficiaud

Milestone: To Be DeterminedBoost 1.65.0

comment:8 Changed 18 months ago by Raffi Enficiaud

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

comment:9 Changed 17 months ago by Raffi Enficiaud

Resolution: fixed
Status: assignedclosed

In master, rev 3ddb0e0d29e8ebfe4ba20921a3d366f7b5b837b2

Note: See TracTickets for help on using tickets.