[Boost.Test] Understanding the correct use of BOOST_CHECK_CLOSE and BOOST_CHECK_CLOSE_FRACTION
I am trying to understand how to be use BOOST_CHECK_CLOSE and BOOST_CHECK_CLOSE_FRACTION for my problem. My problem is being able to check that two floating point values agree within 12 decimal digits. That is the difference between the two values is smaller than 1e-12. I see from the documentation that BOOST_CHECK_CLOSE requires a percent of agreement while BOOST_CHECK_CLOSE_FRACTION requires a fraction value. So when I used BOOST_CHECK_CLOSE_FRACTION to compare two value I got output that I didn't know how to read: /test_sgp4_orbit_data.cpp(52): error in "default_calculate_semi_major_test": difference{1e-12} between result{1.1219271770198256} and 1.1219271773271688{1.1219271773271688} exceeds 9.9999999999999998e-13 I used BOOST_CHECK_CLOSE_FRACTION as: BOOST_CHECK_CLOSE_FRACTION ( result, 1.1219271773271688, 1e-12 ); What I am intending is if 'result' and the value differ by more than 1e-12 then I have an error. If the difference is smaller than 1e-12 I wish to have the comparison succeed. From the output I don't know why the exceeds value is not written as '1e-12' since that is what I used. Where am I going wrong in my use of BOOST_CHECK_CLOSE_FRACTION? Stephen Stephen Torri, PhD NAVAL SURFACE WARFARE CENTER DAHLGREN 17214 Ave B Suite 121 Dahlgren, Va. 22448 540-653-1082 I am not a contracting officer. I cannot modify or initiate contracts, nor do I have the authority to financially commit the government in any way.
AMDG Torri, Stephen CIV NSWCDD, W15 wrote:
I am trying to understand how to be use BOOST_CHECK_CLOSE and BOOST_CHECK_CLOSE_FRACTION for my problem. My problem is being able to check that two floating point values agree within 12 decimal digits. That is the difference between the two values is smaller than 1e-12. I see from the documentation that BOOST_CHECK_CLOSE requires a percent of agreement while BOOST_CHECK_CLOSE_FRACTION requires a fraction value. So when I used BOOST_CHECK_CLOSE_FRACTION to compare two value I got output that I didn't know how to read:
/test_sgp4_orbit_data.cpp(52): error in "default_calculate_semi_major_test": difference{1e-12} between result{1.1219271770198256} and 1.1219271773271688{1.1219271773271688} exceeds 9.9999999999999998e-13
I used BOOST_CHECK_CLOSE_FRACTION as:
BOOST_CHECK_CLOSE_FRACTION ( result, 1.1219271773271688, 1e-12 );
What I am intending is if 'result' and the value differ by more than 1e-12 then I have an error. If the difference is smaller than 1e-12 I wish to have the comparison succeed. From the output I don't know why the exceeds value is not written as '1e-12' since that is what I used.
Where am I going wrong in my use of BOOST_CHECK_CLOSE_FRACTION?
Nowhere. 1e-12 cannot be represented exactly in floating point. It gets rounded to the nearest representable value which is printed as 9.9999999999999998e-13 In Christ, Steven Watanabe
Ok. Thanks for the help. That helps me to work on writing my tests. Stephen
In retrospect I think I am using BOOST_CHECK_CLOSE_FRACTION incorrectly. What I want to do is take two values and compute their absolute variance. I want to then take that variance and determine if it is greater than (failure) or less than or equal a tolerance (success). I think I need to use BOOST_CHECK _LE instead as follows: double a = 1.0e-12; double b = 1.0e-13; double tolerance = 1.0e-12; BOOST_CHECK_LE ( fabs ( a - b ), tolerance ); So I could make a macro called: /*! * \brief Check the absolute variance between two floating point or double values * \param L left float/double value * \param R right float/double value * \param T tolerance of comparison */ #define BOOST_CHECK_VARIANCE( L, R, T ) BOOST_CHECK_LE ( fabs ( L - R ), T ) Stephen Stephen Torri, PhD NAVAL SURFACE WARFARE CENTER DAHLGREN 17214 Ave B Suite 121 Dahlgren, Va. 22448 540-653-1082 I am not a contracting officer. I cannot modify or initiate contracts, nor do I have the authority to financially commit the government in any way.
Torri, Stephen CIV NSWCDD, W15
BOOST_CHECK_LE ( fabs ( a - b ), tolerance );
Use BOOST_CHECK_SMALL( a-b, tolerance ). That said I really recommend you to use assertions based on relative errors, since they give more reliable results. Gennadiy
From: boost-users-bounces@lists.boost.org on behalf of Gennadiy Rozental Sent: Thu 9/9/2010 8:33 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users][Boost.Test] Understanding the correct use of BOOST_CHECK_CLOSE and >BOOST_CHECK_CLOSE_FRACTION
Use BOOST_CHECK_SMALL( a-b, tolerance ).
That said I really recommend you to use assertions based on relative errors, since they give more reliable results.
Thanks for the input. On the advice of a co-worker I am using a normalized variance ( value - reference ) / reference. Of course you can't use the check if the reference is zero. In that case I simply use BOOST_CHECK_EQUAL. Here is how I did the macro: #define BOOST_CHECK_VARIANCE( L, R ) BOOST_CHECK_LT ( fabs ( ( L - R ) / R ), 1e-9 ) I can change that to be #define BOOST_CHECK_VARIANCE( L, R ) BOOST_CHECK_SMALL ( ( L - R ) / R, 1e-9 ) What would have to do finish the implementation of a proper print algorithm so that 9.999999e-13 is displayed as 1e-12? Stephen
Torri, Stephen CIV NSWCDD, W15
From: boost-users-bounces <at> lists.boost.org on behalf of Gennadiy Rozental Sent: Thu 9/9/2010 8:33 PM To: boost-users <at> lists.boost.org Subject: Re: [Boost-users][Boost.Test] Understanding the correct use of
BOOST_CHECK_CLOSE and >BOOST_CHECK_CLOSE_FRACTION
Use BOOST_CHECK_SMALL( a-b, tolerance ).
That said I really recommend you to use assertions based on relative errors, since they give more reliable results.
Thanks for the input. On the advice of a co-worker I am using a normalized variance ( value - reference ) / reference. Of course you can't use the check if the reference is zero. In that case I simply use BOOST_CHECK_EQUAL. Here is how I did the macro:
#define BOOST_CHECK_VARIANCE( L, R ) BOOST_CHECK_LT ( fabs ( ( L - R ) / R ), 1e-9 )
This is pretty much what BOOST_CHECK_CLOSE_FRACTION is doing, but it's more precise. It checks: (L-R)/R < T && (L-R)/L < T
I can change that to be
#define BOOST_CHECK_VARIANCE( L, R ) BOOST_CHECK_SMALL ( ( L - R ) / R, 1e-9 )
What would have to do finish the implementation of a proper print algorithm so
Just use BOOST_CHECK_CLOSE_FRACTION if you ask me. that 9.999999e-13 is
displayed as 1e-12?
One need to implement this algorithm: http://tinyurl.com/28du8d4 Gennadiy
Steven Watanabe
Nowhere. 1e-12 cannot be represented exactly in floating point. It gets rounded to the nearest representable value which is printed as 9.9999999999999998e-13
This is solvable problem, but I never got to finish implementation of proper print algorithm (any takers?). These days I am very busy at work, so I wouldn't expect this to resolve by itself any time soon ;) Gennadiy
participants (3)
-
Gennadiy Rozental
-
Steven Watanabe
-
Torri, Stephen CIV NSWCDD, W15