On 7 April 2010 17:26, Paul A. Bristow <pbristow@hetp.u-net.com> wrote:

  

From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Brian O'Kennedy
Sent: Wednesday, April 07, 2010 3:16 PM
To: Boost-users@lists.boost.org
Subject: [Boost-users] [Boost.Test] Floating point NAN comparison

 

Hi, 

 

This bit of Boost.Test code fails:

 

//////////////////////////////////////////////////////////////////////

BOOST_AUTO_TEST_CASE( nantest )

{

  float a,b;

  a = b = 1.0;

  BOOST_CHECK_EQUAL( a, b );  // passes

  a = b = NAN;

  BOOST_CHECK_EQUAL( a, b );  // fails

}

//////////////////////////////////////////////////////////////////////

 

The failure is because, by definition, NAN != NAN. What I'm after is a test macro which takes this into account and will pass the equality test when both elements are NAN. 

 

BOOST_CHECK_CLOSE has the same behaviour.  Is the best solution to write my own custom predicate? 

 

You can use the TR1 bool isnan(a) function in the boost.math to check for NaNness.

 

\boost-sandbox\math_toolkit\libs\math\example\fpclassify.cpp gives some examples of

 

using boost::math::isnan;

 

\boost_1_42_0\libs\math\test\test_classify.cpp(68): BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);

 

gives some examples of using boost.test with NaNs

 

See the boost_pdf_1_41_0/math.pdf for details.

 

HTH

 

Paul

 

 


Hi, 

Thanks for the reply, but you misunderstood my question slightly. I can check IF something is a NAN simply by doing: 
   BOOST_CHECK( std::isnan( a ) );
but what I really want is to cycle through two std::vector<float> vectors and compare them. Doing so the normal way reports an inequality when elements at the same index in both vectors are NAN. I want that check to succeed, since as far as I'm concerned the vectors are equal if they contain the same values. 

I solved this by writing a custom predicate for Boost.Test:

/// ------------------ SNIP --------------------------------
#include <boost/test/floating_point_comparison.hpp>

// NAN safe floating point equals for use in BOOST_TEST clauses 
// Will pass when both floats are NAN, or when a==b within tolerance
// BOOST_CHECK( nancomp( a, b ) );

inline boost::test_tools::predicate_result nancomp( float a, float b ) 
{
 if ( std::isnan( a ) && std::isnan( b ) )  
 {
  return true;
 

  if ( ! boost::test_tools::check_is_close( a, b, boost::test_tools::fraction_tolerance(1.e-5)) )
  {
    boost::test_tools::predicate_result res(false);
    res.message() << "[" << a << " != " << b << "]";
    return res;
  }

  return true;
}

/// ------------------ /SNIP --------------------------------

 which allows me to do this:

 BOOST_CHECK( nancomp( NAN, NAN ) );   // pass BOOST_CHECK( nancomp( 1.0, 1.0 ) );        // pass
 BOOST_CHECK( nancomp( 1.0, NAN ) );      // fail BOOST_CHECK( nancomp( 1.0, 1.2 ) );       // fail


 There might be a better way, if so, let me know!

cheers, 
 Brian

 


_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users