Boost logo

Boost :

From: Paul A Bristow (pbristow_at_[hidden])
Date: 2007-05-23 07:42:19


 

>-----Original Message-----
>From: boost-bounces_at_[hidden]
>[mailto:boost-bounces_at_[hidden]] On Behalf Of Gennadiy Rozental
>Sent: 17 May 2007 19:09
>To: boost_at_[hidden]
>Subject: Re: [boost] [test] comparing floating point values
>
>
>"Paul A Bristow" <pbristow_at_[hidden]> wrote in message
>news:001601c7979f$b5c37bb0$0200a8c0_at_hetp7...
>>>> Why do you expect two infinity values to be close with any
>tolerance?
>>>
>>>Interesting question: if the too values are the same, then I
>>>would have
>>>expected BOOST_CHECK_CLOSE to pass. But then we get into
>>>philisophical
>>>discussions about whether two infinities are really the same :-)
>>
>> Well we certainly don't want any philosophical discussions :-))

>This is not exactly true in general. BOOST_CHECK uses operator==.
>BOOST_CHECK_CLOSE doesn't compare bit patterns either. It uses
>some advanced algorithm. So we may decide what is the desirable outcome.

Agreed (and this is different from BOOST_CHECK_EQUAL, where being different from the IEEE spec and operator== would be confusing).

BUT there IS a need to be able to see if you get NaN or infinity as a result - John and I have found this in checking the math
toolkit. To do this we must have a Standard way of doing this - Standards writers please note the inordinate confusion caused by
the previous lack of a Standard way of doing something very simple (but platform specific), having created a Standard way of
creating infinity and NaNs in numeric_limits. Boost should soon have this when Johan Råde 's TR1 code comes up for review - and I
trust acceptance.

For BOOST_CHECK_CLOSE (and BOOST_CHECK_CLOSE_FRACTION) we (well Gennadiy at least ;-) can decide what the rules are.

At present 1.34, my tests attached show that:

>0. == 0. passes, whatever the tolerance (as long as it isn't NaN!).

>NaN == NaN - fails
>
>Inf == Inf - fails

>My vote would be to keep it this way.

OK - but it needs documenting, perhaps with the attached example code.

If you need (and our experience is that you do) to consider NaN and infinity then use the TR1 functions:

template<class T> bool isfinite(T x);
template<class T> bool isinf(T x);
template<class T> bool isnan(T x);

for example, if you expect a possible infinity result:
perhaps from a dividebyzero caused by an underflow.

  double d = 1.23;
  double n = 0.; // force a divide by zero,
  double r = d / n; // expecting an infinity result.
  // cout << r << endl; // 1.#INF

  if (isfinite(r))
  {
    BOOST_CHECK_CLOSE(r, 1., 0.000001);
  }
  else
  {// If not finite then we expect the result to be infinity.
    BOOST_CHECK(isinf(r));
  }

or mark a fail as expected.

And similarly if you expect a NaN result.

This extra code is a possible reason why BOOST_CHECK_CLOSE might do something smarter with non-finites. But this code is clear, if
a hassle to write.

Paul

---
Paul A Bristow
Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB
+44 1539561830 & SMS, Mobile +44 7714 330204 & SMS
pbristow_at_[hidden]
 



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk