annotate DEPENDENCIES/generic/include/boost/test/floating_point_comparison.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // (C) Copyright Gennadiy Rozental 2001-2008.
Chris@16 2 // Distributed under the Boost Software License, Version 1.0.
Chris@16 3 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 // See http://www.boost.org/libs/test for the library home page.
Chris@16 7 //
Chris@16 8 // File : $RCSfile$
Chris@16 9 //
Chris@101 10 // Version : $Revision$
Chris@16 11 //
Chris@16 12 // Description : defines algoirthms for comparing 2 floating point values
Chris@16 13 // ***************************************************************************
Chris@16 14
Chris@16 15 #ifndef BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
Chris@16 16 #define BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
Chris@16 17
Chris@16 18 // Boost.Test
Chris@16 19 #include <boost/test/detail/global_typedef.hpp>
Chris@16 20 #include <boost/test/utils/class_properties.hpp>
Chris@16 21 #include <boost/test/predicate_result.hpp>
Chris@16 22
Chris@16 23 // Boost
Chris@16 24 #include <boost/limits.hpp> // for std::numeric_limits
Chris@16 25 #include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
Chris@16 26 #include <boost/static_assert.hpp>
Chris@16 27
Chris@16 28 #include <boost/test/detail/suppress_warnings.hpp>
Chris@16 29
Chris@16 30 //____________________________________________________________________________//
Chris@16 31
Chris@16 32 namespace boost {
Chris@16 33
Chris@16 34 namespace test_tools {
Chris@16 35
Chris@16 36 using unit_test::readonly_property;
Chris@16 37
Chris@16 38 // ************************************************************************** //
Chris@16 39 // ************** floating_point_comparison_type ************** //
Chris@16 40 // ************************************************************************** //
Chris@16 41
Chris@16 42 enum floating_point_comparison_type {
Chris@16 43 FPC_STRONG, // "Very close" - equation 1' in docs, the default
Chris@16 44 FPC_WEAK // "Close enough" - equation 2' in docs.
Chris@16 45
Chris@16 46 };
Chris@16 47
Chris@16 48 // ************************************************************************** //
Chris@16 49 // ************** details ************** //
Chris@16 50 // ************************************************************************** //
Chris@16 51
Chris@16 52 namespace tt_detail {
Chris@16 53
Chris@16 54 // FPT is Floating-Point Type: float, double, long double or User-Defined.
Chris@16 55 template<typename FPT>
Chris@16 56 inline FPT
Chris@16 57 fpt_abs( FPT fpv )
Chris@16 58 {
Chris@16 59 return fpv < static_cast<FPT>(0) ? -fpv : fpv;
Chris@16 60 }
Chris@16 61
Chris@16 62 //____________________________________________________________________________//
Chris@16 63
Chris@16 64 template<typename FPT>
Chris@16 65 struct fpt_limits {
Chris@16 66 static FPT min_value()
Chris@16 67 {
Chris@16 68 return std::numeric_limits<FPT>::is_specialized
Chris@16 69 ? (std::numeric_limits<FPT>::min)()
Chris@16 70 : 0;
Chris@16 71 }
Chris@16 72 static FPT max_value()
Chris@16 73 {
Chris@16 74 return std::numeric_limits<FPT>::is_specialized
Chris@16 75 ? (std::numeric_limits<FPT>::max)()
Chris@16 76 : static_cast<FPT>(1000000); // for the our purpuses it doesn't really matter what value is returned here
Chris@16 77 }
Chris@16 78 };
Chris@16 79
Chris@16 80 //____________________________________________________________________________//
Chris@16 81
Chris@16 82 // both f1 and f2 are unsigned here
Chris@16 83 template<typename FPT>
Chris@16 84 inline FPT
Chris@16 85 safe_fpt_division( FPT f1, FPT f2 )
Chris@16 86 {
Chris@16 87 // Avoid overflow.
Chris@16 88 if( (f2 < static_cast<FPT>(1)) && (f1 > f2*fpt_limits<FPT>::max_value()) )
Chris@16 89 return fpt_limits<FPT>::max_value();
Chris@16 90
Chris@16 91 // Avoid underflow.
Chris@16 92 if( (f1 == static_cast<FPT>(0)) ||
Chris@16 93 ((f2 > static_cast<FPT>(1)) && (f1 < f2*fpt_limits<FPT>::min_value())) )
Chris@16 94 return static_cast<FPT>(0);
Chris@16 95
Chris@16 96 return f1/f2;
Chris@16 97 }
Chris@16 98
Chris@16 99 //____________________________________________________________________________//
Chris@16 100
Chris@16 101 } // namespace tt_detail
Chris@16 102
Chris@16 103 // ************************************************************************** //
Chris@16 104 // ************** tolerance presentation types ************** //
Chris@16 105 // ************************************************************************** //
Chris@16 106
Chris@16 107 template<typename FPT>
Chris@16 108 struct percent_tolerance_t {
Chris@16 109 explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
Chris@16 110
Chris@16 111 FPT m_value;
Chris@16 112 };
Chris@16 113
Chris@16 114 //____________________________________________________________________________//
Chris@16 115
Chris@16 116 template<typename Out,typename FPT>
Chris@16 117 Out& operator<<( Out& out, percent_tolerance_t<FPT> t )
Chris@16 118 {
Chris@16 119 return out << t.m_value;
Chris@16 120 }
Chris@16 121
Chris@16 122 //____________________________________________________________________________//
Chris@16 123
Chris@16 124 template<typename FPT>
Chris@16 125 inline percent_tolerance_t<FPT>
Chris@16 126 percent_tolerance( FPT v )
Chris@16 127 {
Chris@16 128 return percent_tolerance_t<FPT>( v );
Chris@16 129 }
Chris@16 130
Chris@16 131 //____________________________________________________________________________//
Chris@16 132
Chris@16 133 template<typename FPT>
Chris@16 134 struct fraction_tolerance_t {
Chris@16 135 explicit fraction_tolerance_t( FPT v ) : m_value( v ) {}
Chris@16 136
Chris@16 137 FPT m_value;
Chris@16 138 };
Chris@16 139
Chris@16 140 //____________________________________________________________________________//
Chris@16 141
Chris@16 142 template<typename Out,typename FPT>
Chris@16 143 Out& operator<<( Out& out, fraction_tolerance_t<FPT> t )
Chris@16 144 {
Chris@16 145 return out << t.m_value;
Chris@16 146 }
Chris@16 147
Chris@16 148 //____________________________________________________________________________//
Chris@16 149
Chris@16 150 template<typename FPT>
Chris@16 151 inline fraction_tolerance_t<FPT>
Chris@16 152 fraction_tolerance( FPT v )
Chris@16 153 {
Chris@16 154 return fraction_tolerance_t<FPT>( v );
Chris@16 155 }
Chris@16 156
Chris@16 157 //____________________________________________________________________________//
Chris@16 158
Chris@16 159 // ************************************************************************** //
Chris@16 160 // ************** close_at_tolerance ************** //
Chris@16 161 // ************************************************************************** //
Chris@16 162
Chris@16 163 template<typename FPT>
Chris@16 164 class close_at_tolerance {
Chris@16 165 public:
Chris@16 166 // Public typedefs
Chris@16 167 typedef bool result_type;
Chris@16 168
Chris@16 169 // Constructor
Chris@16 170 template<typename ToleranceBaseType>
Chris@16 171 explicit close_at_tolerance( percent_tolerance_t<ToleranceBaseType> tolerance,
Chris@16 172 floating_point_comparison_type fpc_type = FPC_STRONG )
Chris@16 173 : p_fraction_tolerance( tt_detail::fpt_abs( static_cast<FPT>(0.01)*tolerance.m_value ) )
Chris@16 174 , p_strong_or_weak( fpc_type == FPC_STRONG )
Chris@16 175 , m_report_modifier( 100. )
Chris@16 176 {}
Chris@16 177 template<typename ToleranceBaseType>
Chris@16 178 explicit close_at_tolerance( fraction_tolerance_t<ToleranceBaseType> tolerance,
Chris@16 179 floating_point_comparison_type fpc_type = FPC_STRONG )
Chris@16 180 : p_fraction_tolerance( tt_detail::fpt_abs( tolerance.m_value ) )
Chris@16 181 , p_strong_or_weak( fpc_type == FPC_STRONG )
Chris@16 182 , m_report_modifier( 1. )
Chris@16 183 {}
Chris@16 184
Chris@16 185 predicate_result operator()( FPT left, FPT right ) const
Chris@16 186 {
Chris@16 187 FPT diff = tt_detail::fpt_abs( left - right );
Chris@16 188 FPT d1 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( right ) );
Chris@16 189 FPT d2 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( left ) );
Chris@16 190
Chris@16 191 predicate_result res( p_strong_or_weak
Chris@16 192 ? (d1 <= p_fraction_tolerance.get() && d2 <= p_fraction_tolerance.get())
Chris@16 193 : (d1 <= p_fraction_tolerance.get() || d2 <= p_fraction_tolerance.get()) );
Chris@16 194
Chris@16 195 if( !res )
Chris@16 196 res.message() << (( d1 <= p_fraction_tolerance.get() ? d2 : d1 ) * m_report_modifier);
Chris@16 197
Chris@16 198 return res;
Chris@16 199 }
Chris@16 200
Chris@16 201 // Public properties
Chris@16 202 readonly_property<FPT> p_fraction_tolerance;
Chris@16 203 readonly_property<bool> p_strong_or_weak;
Chris@16 204 private:
Chris@16 205 // Data members
Chris@16 206 FPT m_report_modifier;
Chris@16 207 };
Chris@16 208
Chris@16 209 //____________________________________________________________________________//
Chris@16 210
Chris@16 211 // ************************************************************************** //
Chris@16 212 // ************** check_is_close ************** //
Chris@16 213 // ************************************************************************** //
Chris@16 214
Chris@16 215 struct BOOST_TEST_DECL check_is_close_t {
Chris@16 216 // Public typedefs
Chris@16 217 typedef bool result_type;
Chris@16 218
Chris@16 219 template<typename FPT1, typename FPT2, typename ToleranceBaseType>
Chris@16 220 predicate_result
Chris@16 221 operator()( FPT1 left, FPT2 right, percent_tolerance_t<ToleranceBaseType> tolerance,
Chris@16 222 floating_point_comparison_type fpc_type = FPC_STRONG ) const
Chris@16 223 {
Chris@16 224 // deduce "better" type from types of arguments being compared
Chris@16 225 // if one type is floating and the second integral we use floating type and
Chris@16 226 // value of integral type is promoted to the floating. The same for float and double
Chris@16 227 // But we don't want to compare two values of integral types using this tool.
Chris@16 228 typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype FPT;
Chris@16 229 BOOST_STATIC_ASSERT( !is_integral<FPT>::value );
Chris@16 230
Chris@16 231 close_at_tolerance<FPT> pred( tolerance, fpc_type );
Chris@16 232
Chris@16 233 return pred( left, right );
Chris@16 234 }
Chris@16 235 template<typename FPT1, typename FPT2, typename ToleranceBaseType>
Chris@16 236 predicate_result
Chris@16 237 operator()( FPT1 left, FPT2 right, fraction_tolerance_t<ToleranceBaseType> tolerance,
Chris@16 238 floating_point_comparison_type fpc_type = FPC_STRONG ) const
Chris@16 239 {
Chris@16 240 // same as in a comment above
Chris@16 241 typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype FPT;
Chris@16 242 BOOST_STATIC_ASSERT( !is_integral<FPT>::value );
Chris@16 243
Chris@16 244 close_at_tolerance<FPT> pred( tolerance, fpc_type );
Chris@16 245
Chris@16 246 return pred( left, right );
Chris@16 247 }
Chris@16 248 };
Chris@16 249
Chris@16 250 namespace {
Chris@16 251 check_is_close_t const& check_is_close = unit_test::ut_detail::static_constant<check_is_close_t>::value;
Chris@16 252 }
Chris@16 253
Chris@16 254 //____________________________________________________________________________//
Chris@16 255
Chris@16 256 // ************************************************************************** //
Chris@16 257 // ************** check_is_small ************** //
Chris@16 258 // ************************************************************************** //
Chris@16 259
Chris@16 260 struct BOOST_TEST_DECL check_is_small_t {
Chris@16 261 // Public typedefs
Chris@16 262 typedef bool result_type;
Chris@16 263
Chris@16 264 template<typename FPT>
Chris@16 265 bool
Chris@16 266 operator()( FPT fpv, FPT tolerance ) const
Chris@16 267 {
Chris@16 268 return tt_detail::fpt_abs( fpv ) < tt_detail::fpt_abs( tolerance );
Chris@16 269 }
Chris@16 270 };
Chris@16 271
Chris@16 272 namespace {
Chris@16 273 check_is_small_t const& check_is_small = unit_test::ut_detail::static_constant<check_is_small_t>::value;
Chris@16 274 }
Chris@16 275
Chris@16 276 //____________________________________________________________________________//
Chris@16 277
Chris@16 278 } // namespace test_tools
Chris@16 279
Chris@16 280 } // namespace boost
Chris@16 281
Chris@16 282 //____________________________________________________________________________//
Chris@16 283
Chris@16 284 #include <boost/test/detail/enable_warnings.hpp>
Chris@16 285
Chris@16 286 #endif // BOOST_FLOATING_POINT_COMAPARISON_HPP_071894GER