Opened 5 years ago
Closed 5 years ago
#13011 closed Bugs (fixed)
BOOST_TEST broken with floating point relational operators
Reported by: | 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 , 5 years ago
comment:2 by , 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 , 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 , 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 , 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 , 5 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:7 by , 5 years ago
Milestone: | To Be Determined → Boost 1.65.0 |
---|
comment:9 by , 5 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
In master, rev 3ddb0e0d29e8ebfe4ba20921a3d366f7b5b837b2
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: