
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Gennadiy Rozental Sent: 17 May 2007 19:09 To: boost@lists.boost.org Subject: Re: [boost] [test] comparing floating point values
"Paul A Bristow" <pbristow@hetp.u-net.com> wrote in message news:001601c7979f$b5c37bb0$0200a8c0@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@hetp.u-net.com