
"John Maddock" <john@johnmaddock.co.uk> wrote in message news:097901c6b728$a7d1b0b0$6e240d52@fuji...
Gennadiy Rozental wrote:
Should be in cvs by now.
Apparently this was not quite as simple as I thought it was, because we still need to handle the 0/0 case, the following patch does the trick:
cvs diff: Diffing boost/test Index: boost/test/floating_point_comparison.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/test/floating_point_comparison.hpp,v retrieving revision 1.28 diff -u -r1.28 floating_point_comparison.hpp --- boost/test/floating_point_comparison.hpp 28 Jul 2006 15:01:01 -00001.28 +++ boost/test/floating_point_comparison.hpp 3 Aug 2006 18:08:39 -0000 @@ -71,6 +71,18 @@ f2 > static_cast<FPT>(1) && f1 < f2 * (std::numeric_limits<FPT>::mi n)() ) return static_cast<FPT>(0); } + else if(f1 == 0) + { + // Avoid 0 / 0, since we're calculating relative error + // the result really is zero here no matter what the denominator: + return 0; + } + else if(f2 == 0) + { + // We have an infinite relative error, in practice any + // big number returned here will cause our test to fail: + return 1000000; // any really big number will do. + }
return f1/f2; }
Both of the else clauses here only kick in when there is no numeric_limits support BTW.
Does this look OK?
I don't really like this. I may consider something like this: namespace tt_detail { template<typename FPT> struct generic_fpt_limits { FPT min_value() { return static_cast<FPT>(0); } FPT max_value() { return static_cast<FPT>(1000000); } }; template<typename FPT> struct numeric_limits { FPT min_value() { return (std::numeric_limits<FPT>::min)(); } FPT max_value() { return (std::numeric_limits<FPT>::min)(); } }; template<typename FPT> struct fpt_limits : mpl::if_<std::numeric_limits<FPT>::is_specialized,numeric_fpt_limits,generic_fpt_limits> {}; template<typename FPT> inline FPT safe_fpt_division( FPT f1, FPT f2 ) { // Avoid overflow. if( f2 < static_cast<FPT>(1) && f1 > f2 * fpt_limits<FPT>::max_value() ) return fpt_limits<FPT>::max_value(); // Avoid underflow. if( f1 == static_cast<FPT>(0) || f2 > static_cast<FPT>(1) && f1 < f2 * fpt_limits<FPT>::min_value() ) return static_cast<FPT>(0); return f1/f2; } } // namespace tt_detail Could you try this? Gennadiy