[Unit Test] default FPC_STRONG limtations when checking close to 0.
After wondering why my BOOST_CHECK_CLOSE(some_number_close_to_zero, 0.0) hadn't been working, I found that the default comparison type is FPC_STRONG which means the ration between the abs val of the difference and BOTH values must be < tolerance but this doesn't turn out to be true (running through what safe_fpt_division outputs atm ... difference between 0.0{0} and 0.0 std::numeric_limits<double>::epsilon(){-2.2204460492503131e-16} exceeds 0.01% It should work using FPC_WEAK but I can't find a way through the test_tools to easily change this. I have three solutions at this time. 1) Use BOOST_CHECK_SMALL. However, I have code that loops through matrix indicies like: for (int j = 0; j < matrix.col; j++) for (int i = 0; i < matrix.row; i++) BOOST_CHECK_CLOSE(matrix(i,j), data(i,j), tolerance); I'm going to have to use an if statement for the special case where I'm testing against 0 and it doesn't use the tolerance anyway so the test is completely different. Theres another number to determine "how small" the number should be. 2) Use check_is_close explicitly and change the default comparison type to FPC_WEAK. This means going outside the nice auto-unit-test and test-tools framework which although I'm fine with, other programmers writing test cases on my team might not be. 3) Define my own macro to simplify solution 2. Something along the lines of: CHECK_IS_CLOSE_WEAK(x,y,t) { check_is_close(x ,y,t, FPC_WEAK); } Are there any other recommended solutions?
"Chris Fairles"
2) Use check_is_close explicitly and change the default comparison type to FPC_WEAK. This means going outside the nice auto-unit-test and test-tools framework which although I'm fine with, other programmers writing test cases on my team might not be.
You can combine check_is_close with BOOST_CHECK_PREDICATE to get nice test tools output. Gennadiy
Thanks for the suggestion, tried a few things. I have
#define CHECK_IS_CLOSE_WEAK(x, y, t) \
boost::test_tools::check_is_close((x),(y),
boost::test_tools::percent_tolerance(t), boost::test_tools::FPC_WEAK)
which works fine with when either x or y is 0. I tried the predicate
method, something like:
BOOST_CHECK_PREDICATE(boost::test_tools::check_is_close,
(first)(second)(boost::test_tools::percent_tolerance( e
))(boost::test_tools::FPC_WEAK))
But this fails
check boost::test_tools::check_is_close( m_cmp(i,j), m(i,j),
boost::test_tools::percent_tolerance( tolerance ),
boost::test_tools::FPC_WEAK ) failed for ( 0, -2.2204460492503131e-16,
1e-05, 1 )
Am I not using the predicate correctly?
On 5/31/07, Gennadiy Rozental
"Chris Fairles"
wrote in message news:fac6bb500705310734l20adccxd3c2656306af0a7@mail.gmail.com... 2) Use check_is_close explicitly and change the default comparison type to FPC_WEAK. This means going outside the nice auto-unit-test and test-tools framework which although I'm fine with, other programmers writing test cases on my team might not be.
You can combine check_is_close with BOOST_CHECK_PREDICATE to get nice test tools output.
Gennadiy
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
"Chris Fairles"
Thanks for the suggestion, tried a few things. I have #define CHECK_IS_CLOSE_WEAK(x, y, t) \ boost::test_tools::check_is_close((x),(y), boost::test_tools::percent_tolerance(t), boost::test_tools::FPC_WEAK)
which works fine with when either x or y is 0. I tried the predicate method, something like:
This is wrong. check_is_close can't return true if either x or y is zero regardless of weak/strong flag. Relative errors are 1 and Inf. Both are more than 1e-05
BOOST_CHECK_PREDICATE(boost::test_tools::check_is_close, (first)(second)(boost::test_tools::percent_tolerance( e ))(boost::test_tools::FPC_WEAK))
But this fails check boost::test_tools::check_is_close( m_cmp(i,j), m(i,j), boost::test_tools::percent_tolerance( tolerance ), boost::test_tools::FPC_WEAK ) failed for ( 0, -2.2204460492503131e-16, 1e-05, 1 )
As expected.
Am I not using the predicate correctly?
You should use differerent predicate, which uses check_is_close in regular cases and check_is_small in case if either of the arguments is zero. It's still not exactly correct, since in general you can't use the same tolerance for both comparizons: one is relative, another is absolute. Gennadiy
participants (2)
-
Chris Fairles
-
Gennadiy Rozental