Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost.Test] Floating point NAN comparison
From: Brian O'Kennedy (brokenn_at_[hidden])
Date: 2010-04-08 03:52:16


On 7 April 2010 17:26, Paul A. Bristow <pbristow_at_[hidden]> wrote:

>
>
> *From:* boost-users-bounces_at_[hidden] [mailto:
> boost-users-bounces_at_[hidden]] *On Behalf Of *Brian O'Kennedy
> *Sent:* Wednesday, April 07, 2010 3:16 PM
> *To:* Boost-users_at_[hidden]
> *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_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net