Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BOOST_CHECK_CLOSE fails even if the two values are below the threshold

I'm performing unit testing using boost. When I use BOOST_CHECK_CLOSE I get this failure message:

difference{inf%} {-6.9388939e-18} and (0.0){0} exceeds 1.0000000000000001e-05%

It sounds weird to me as the difference between -6.9388939e-18 and 0.0 is below 1.0000000000000001e-05%. Furthermore, I do no understand why it says that the difference is infinite.

Any idea about the reason behind this behavior?

like image 817
gcswoosh Avatar asked Mar 22 '15 15:03

gcswoosh


1 Answers

BOOST_CHECK_CLOSE uses Knuth's tolerance predicate to compare floating point numbers, which is

abs(x - y) / abs(x) <= eps && abs(x - y) / abs(y) <= eps

Where x, y are the numbers to compare and eps is the tolerance epsilon. In other words, it tests that x is not more than eps percent1 of x away from y, and vice versa.

This predicate has many properties to recommend it (particularly when working with very big or very small numbers, or when the orders of magnitude of x and y are not known/fixed), but a drawback is that it has a singularity at zero (nothing is close to zero, according to it, because eps percent of zero is zero, leading to a tolerance of zero), and that is the problem you ran into.

You can replace it with

BOOST_CHECK_SMALL(x - y, epsilon);

to use an absolute epsilon value2. Or, since I assume the zero in your test is a fixed number, just

BOOST_CHECK_SMALL(x, epsilon);

1BOOST_CHECK_CLOSE interprets the given epsilon as percentage. I have always wondered why.
2 Note that BOOST_CHECK_SMALL does not interpret the given epsilon as a percentage but as an absolute value.

like image 104
Wintermute Avatar answered Sep 22 '22 05:09

Wintermute