|  | Home | Libraries | People | FAQ | More | 
          Unless you specify otherwise, when two values of floating-point type are
          compared inside assertion BOOST_TEST, operators == and !=
          defined for these types are used. In most cases, however, what we need
          is not an exact equality (or inequality), but to check
          that the two numbers are 'sufficiently close' or 'sufficiently different'.
          In order to do that we need to provide a tolerance
          parameter that will instruct the framework what we consider 'sufficiently
          close'.
        
          We can define a per-test unit tolerance
          for a given floating point type by using decorator
          tolerance:
        
| Code | 
|---|
| #define BOOST_TEST_MODULE tolerance_01 #include <boost/test/included/unit_test.hpp> namespace utf = boost::unit_test; BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(0.00001)) { double x = 10.0000000; double y = 10.0000001; double z = 10.001; BOOST_TEST(x == y); // irrelevant difference BOOST_TEST(x == z); // relevant difference } | 
| Output | 
|---|
| > tolerance_01 Running 1 test case... test.cpp(11): error: in "test1": check x == z has failed [10 != 10.000999999999999]. Relative difference exceeds tolerance [0.0001 > 1e-005] *** 1 failure is detected in the test module "tolerance_01" | 
How the tolerance parameter is processed in detail is described here.
          It is possible to specify floating point comparison tolerance per single
          assertion, by providing manipulator boost::test_tools::tolerance
          as the second argument to BOOST_TEST.
        
| Code | 
|---|
| #define BOOST_TEST_MODULE tolerance_02 #include <boost/test/included/unit_test.hpp> namespace utf = boost::unit_test; namespace tt = boost::test_tools; BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(0.00001)) { double x = 10.0000000; double y = 10.0000001; double z = 10.001; BOOST_TEST(x == y); // irrelevant by default BOOST_TEST(x == y, tt::tolerance(0.0)); BOOST_TEST(x == z); // relevant by default BOOST_TEST(x == z, tt::tolerance(0.001)); } | 
| Output | 
|---|
| > tolerance_02 Running 1 test case... test.cpp(12): error: in "test1": check x == y has failed [10 != 10.000000099999999] test.cpp(14): error: in "test1": check x == z has failed [10 != 10.000999999999999]. Relative difference exceeds tolerance [0.0001 > 1e-005] *** 2 failures are detected in the test module "tolerance_02" | 
| ![[Caution]](../../../../../../../doc/src/images/caution.png) | Caution | 
|---|---|
| 
            The support for manipulators requires that your compiler supports variadic
            macros,  | 
It is possible to specify the tolerance as percentage. At test unit level, the decorator syntax is:
* boost::unit_test::tolerance( boost::test_tools::fpc::percent_tolerance(2.0) ) // equivalent to: boost::unit_test::tolerance( 2.0 / 100 )
At assertion level, the manipulator syntax is:
2.0% boost::test_tools::tolerance() boost::test_tools::tolerance( boost::test_tools::fpc::percent_tolerance(2.0) ) // both equivalent to: boost::test_tools::tolerance( 2.0 / 100 )
          Manipulator tolerance specifies
          the tolerance only for a single floating-point type. This type is deduced
          from form the numeric value passed along the manipulator:
        
| expression | semantics | 
|---|---|
| 
                     | 
                    tolerance for type  | 
| 
                     | 
                    tolerance for type  | 
| 
                     | 
                    tolerance for type  | 
| 
                     | 
                    tolerance for type  | 
| 
                     | 
                    tolerance for a user-defined type  | 
| 
                     | 
                    tolerance for type  | 
| 
                     | 
                    tolerance for type  | 
| 
                     | 
                    tolerance for type  | 
          This is also the case for decorator tolerance.
          In case of the decorator, however, it is possible to apply multiple decorators
          tolerance defining the
          tolerance for different types.
        
          When values of two different floating point types T
          and U are compared, BOOST_TEST uses the tolerance
          specified for type boost::common_type<T, U>::type. For instance, when setting a tolerance
          for mixed float-to-double comparison, the tolerance for type
          double needs to be set.
        
          Given two floating point types T
          and U and their common
          type C, the tolerance specified
          for type C is applied only
          when types T and U are appear as sub-expressions of the
          full expression inside assertion BOOST_TEST. It is not applied
          when T and U are compared inside a function invoked
          during the evaluation of the expression:
        
BOOST_AUTO_TEST_CASE(test, * utf::tolerance(0.02)) { double d1 = 1.00, d2 = 0.99; boost::optional<double> o1 = 1.00, o2 = 0.99; BOOST_TEST(d1 == d2); // with tolerance (double vs. double) BOOST_TEST(o1 == o2); // without tolerance (optional vs. optional) BOOST_TEST(o1 == d2); // without tolerance (optional vs. double) BOOST_TEST(*o1 == *o2); // with tolerance (double vs. double) }
          Finally, note that comparisons for tolerance are also applied to operator<
          with semantics 'less by more than some tolerance`, and other relational
          operators. Also, the tolerance-based comparisons are involved when a more
          complicated expression tree is processed within the assertion body:
        
| Code | 
|---|
| #define BOOST_TEST_MODULE tolerance_03 #include <boost/test/included/unit_test.hpp> namespace utf = boost::unit_test; double x = 10.000000; double d = 0.000001; BOOST_AUTO_TEST_CASE(passing, * utf::tolerance(0.0001)) { BOOST_TEST(x == x + d); // equal with tolerance BOOST_TEST(x >= x + d); // ==> greater-or-equal BOOST_TEST(d == .0); // small with tolerance } BOOST_AUTO_TEST_CASE(failing, * utf::tolerance(0.0001)) { BOOST_TEST(x - d < x); // less, but still too close BOOST_TEST(x - d != x); // unequal but too close BOOST_TEST(d > .0); // positive, but too small BOOST_TEST(d < .0); // not sufficiently negative } | 
| Output | 
|---|
| > tolerance_03 Running 2 test cases... test.cpp(18): error: in "failing": check x - d < x has failed [10 - 1.0000000000000001e-05 >= 10]. Relative difference is within tolerance [1e-06 < 0.001] test.cpp(19): error: in "failing": check x - d != x has failed [10 - 1.0000000000000001e-05 == 10]. Relative difference is within tolerance [1e-06 < 0.001] test.cpp(21): error: in "failing": check d > .0 has failed [1.0000000000000001e-05 <= 0]. Absolute value is within tolerance [|1e-05| < 0.001] test.cpp(22): error: in "failing": check d < .0 has failed [1.0000000000000001e-05 >= 0] *** 4 failures are detected in the test module "tolerance_03" |