18

Can anyone describe the difference in behavior between BOOST_CHECK_CLOSE and BOOST_CHECK_CLOSE_FRACTION? The documentation implies the that both macros treat their third parameter identically, which makes me suspect the documentation is wrong.

In particular, BOOST_CHECK_CLOSE_FRACTION gives me some odd looking results:

error in "...": difference between *expected{0} and *actual{-1.7763568394002506e-16} exceeds 9.9999999999999995e-07

Is there a gotcha because I expect a zero result? I've not been successful at reading through the underlying macro declarations. Please note BOOST_CHECK_SMALL isn't appropriate for my use case (comparing two vectors after a linear algebra operation).

Rhys Ulerich
  • 1,242
  • 1
  • 12
  • 28

3 Answers3

11

According to this discussion, one (BOOST_CHECK_CLOSE) treats the third parameter as expressing a percent, while the other (BOOST_CHECK_CLOSE_FRACTION) treats it as expressing a fraction. So, .01 in the first should be equivalent to .0001 in the second.

Not certain if that explains your problem -- do you get the same odd result with BOOST_CHECK_CLOSE? I wouldn't be shocked if the 0 caused an issue -- but I don't have first hand experience with the macros.

Richard Dunlap
  • 1,957
  • 11
  • 18
  • 1
    Thank you for the response. It does seem that the zero causes the issue, and that similar behavior occurs with one zero argument for both BOOST\_CHECK\_CLOSE and BOOST\_CHECK\_CLOSE\_FRACTION – Rhys Ulerich Jul 13 '09 at 17:00
7

Yes. Zero is not "close" to any value. You can use BOOST_CHECK_SMALL instead.

Gennadiy Rozental
  • 1,905
  • 2
  • 13
  • 17
2

@Gennadiy: Zero can be close to any small value. :-) Relative differences grow arbitrarily large if the expected value is very close to zero.

Here is a workaround function I use to unit-test double values: if the expected value is very small or zero then I check the smallness of the observed value, otherwise I check closeness:

void dbl_check_close(
    double expected, double observed, 
    double small, double pct_tol
) {
    if (std::fabs(expected) < small) {
        BOOST_CHECK_SMALL(observed, small);
    } else {
        BOOST_CHECK_CLOSE(expected, observed, pct_tol);
    }
}

Of course it would be great to have a BOOST_CHECK_SMALL_OR_CLOSE macro that does this automatically. Gennadiy could perhaps talk to the author of Boost.Test ;-)

András Aszódi
  • 8,948
  • 5
  • 48
  • 51