NCBI C++ ToolKit
floating_point_comparison.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 // (C) Copyright Gennadiy Rozental 2001-2008.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 // File : $RCSfile$
9 //
10 // Version : $Revision: 46904 $
11 //
12 // Description : defines algoirthms for comparing 2 floating point values
13 // ***************************************************************************
14 
15 /*
16  * $Id: floating_point_comparison.hpp 46904 2010-08-23 15:17:09Z satskyse $
17  * NOTE: This file was modified from its original version 1.39.0
18  * to fit the NCBI C++ Toolkit structure and namespaces.
19  *
20  * Disclaimer: The boost code is not supported by the C++ Toolkit group.
21  * Therefore please do not use this header directly. Use the
22  * <util/floating_point.hpp> declared functionality instead.
23  */
24 
25 
26 #ifndef NCBI_BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
27 #define NCBI_BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
28 
29 #ifndef FLOATING_POINT__HPP
30 # error Do not include this header directly. Use <util/floating_point.hpp> instead.
31 #endif
32 
33 
34 #include <limits>
35 
36 //____________________________________________________________________________//
37 
38 namespace ncbi {
39 
40 namespace boost_fp_impl {
41 
42 // ************************************************************************** //
43 // ************** floating_point_comparison_type ************** //
44 // ************************************************************************** //
45 
47  FPC_STRONG, // "Very close" - equation 1' in docs, the default
48  FPC_WEAK // "Close enough" - equation 2' in docs.
49 
50 };
51 
52 // ************************************************************************** //
53 // ************** details ************** //
54 // ************************************************************************** //
55 
56 namespace tt_detail {
57 
58 // FPT is Floating-Point Type: float, double, long double or User-Defined.
59 template<typename FPT>
60 inline FPT
61 fpt_abs( FPT arg )
62 {
63  return arg < static_cast<FPT>(0) ? -arg : arg;
64 }
65 
66 //____________________________________________________________________________//
67 
68 template<typename FPT>
69 struct fpt_limits {
70  static FPT min_value()
71  {
72  return std::numeric_limits<FPT>::is_specialized
74  : 0;
75  }
76  static FPT max_value()
77  {
78  return std::numeric_limits<FPT>::is_specialized
80  : static_cast<FPT>(1000000); // for the our purpuses it doesn't really matter what value is returned here
81  }
82 };
83 
84 //____________________________________________________________________________//
85 
86 // both f1 and f2 are unsigned here
87 template<typename FPT>
88 inline FPT
89 safe_fpt_division( FPT f1, FPT f2 )
90 {
91  // Avoid overflow.
92  if( f2 < static_cast<FPT>(1) && f1 > f2*fpt_limits<FPT>::max_value() )
94 
95  // Avoid underflow.
96  if( (f1 == static_cast<FPT>(0)) ||
97  ((f2 > static_cast<FPT>(1)) && (f1 < f2*fpt_limits<FPT>::min_value())) )
98  return static_cast<FPT>(0);
99 
100  return f1/f2;
101 }
102 
103 //____________________________________________________________________________//
104 
105 } // namespace tt_detail
106 
107 // ************************************************************************** //
108 // ************** tolerance presentation types ************** //
109 // ************************************************************************** //
110 
111 template<typename FPT>
113  explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
114 
115  FPT m_value;
116 };
117 
118 //____________________________________________________________________________//
119 
120 template<typename Out,typename FPT>
122 {
123  return out << t.m_value;
124 }
125 
126 //____________________________________________________________________________//
127 
128 template<typename FPT>
129 inline percent_tolerance_t<FPT>
131 {
132  return percent_tolerance_t<FPT>( v );
133 }
134 
135 //____________________________________________________________________________//
136 
137 template<typename FPT>
139  explicit fraction_tolerance_t( FPT v ) : m_value( v ) {}
140 
141  FPT m_value;
142 };
143 
144 //____________________________________________________________________________//
145 
146 template<typename Out,typename FPT>
148 {
149  return out << t.m_value;
150 }
151 
152 //____________________________________________________________________________//
153 
154 template<typename FPT>
155 inline fraction_tolerance_t<FPT>
157 {
158  return fraction_tolerance_t<FPT>( v );
159 }
160 
161 //____________________________________________________________________________//
162 
163 // ************************************************************************** //
164 // ************** close_at_tolerance ************** //
165 // ************************************************************************** //
166 
167 template<typename FPT>
169 public:
170  // Public typedefs
171  typedef bool result_type;
172 
173  // Constructor
174  template<typename ToleranceBaseType>
177  : p_fraction_tolerance( tt_detail::fpt_abs( static_cast<FPT>(0.01)*tolerance.m_value ) )
178  , p_strong_or_weak( fpc_type == FPC_STRONG )
179  {}
180  template<typename ToleranceBaseType>
183  : p_fraction_tolerance( tt_detail::fpt_abs( tolerance.m_value ) )
184  , p_strong_or_weak( fpc_type == FPC_STRONG )
185  {}
186 
187  bool operator()( FPT left, FPT right ) const
188  {
189  FPT diff = tt_detail::fpt_abs( left - right );
190  FPT d1 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( right ) );
191  FPT d2 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( left ) );
192 
193  return p_strong_or_weak
194  ? (d1 <= p_fraction_tolerance && d2 <= p_fraction_tolerance)
195  : (d1 <= p_fraction_tolerance || d2 <= p_fraction_tolerance);
196  }
197 
198  // Public properties
201 };
202 
203 //____________________________________________________________________________//
204 
205 // ************************************************************************** //
206 // ************** check_is_close ************** //
207 // ************************************************************************** //
208 
210  // Public typedefs
211  typedef bool result_type;
212 
213  template<typename FPT, typename ToleranceBaseType>
214  bool
215  operator()( FPT left, FPT right, percent_tolerance_t<ToleranceBaseType> tolerance,
217  {
218  close_at_tolerance<FPT> pred( tolerance, fpc_type );
219 
220  return pred( left, right );
221  }
222  template<typename FPT, typename ToleranceBaseType>
223  bool
224  operator()( FPT left, FPT right, fraction_tolerance_t<ToleranceBaseType> tolerance,
226  {
227  close_at_tolerance<FPT> pred( tolerance, fpc_type );
228 
229  return pred( left, right );
230  }
231 };
232 
233 namespace {
234 check_is_close_t check_is_close;
235 }
236 
237 //____________________________________________________________________________//
238 
239 // ************************************************************************** //
240 // ************** check_is_small ************** //
241 // ************************************************************************** //
242 
244  // Public typedefs
245  typedef bool result_type;
246 
247  template<typename FPT>
248  bool
249  operator()( FPT fpv, FPT tolerance )
250  {
251  return tt_detail::fpt_abs( fpv ) < tt_detail::fpt_abs( tolerance );
252  }
253 };
254 
255 namespace {
256 check_is_small_t check_is_small; /* NCBI_FAKE_WARNING */
257 }
258 
259 //____________________________________________________________________________//
260 
261 } // namespace boost_fp_impl
262 
263 } // namespace ncbi
264 
265 //____________________________________________________________________________//
266 
267 
268 #endif // NCBI_BOOST_FLOATING_POINT_COMAPARISON_HPP_071894GER
close_at_tolerance(percent_tolerance_t< ToleranceBaseType > tolerance, floating_point_comparison_type fpc_type=FPC_STRONG)
close_at_tolerance(fraction_tolerance_t< ToleranceBaseType > tolerance, floating_point_comparison_type fpc_type=FPC_STRONG)
std::ofstream out("events_result.xml")
main entry point for tests
Out & operator<<(Out &out, percent_tolerance_t< FPT > t)
percent_tolerance_t< FPT > percent_tolerance(FPT v)
fraction_tolerance_t< FPT > fraction_tolerance(FPT v)
Magic spell ;-) needed for some weird compilers... very empiric.
EIPRangeType t
Definition: ncbi_localip.c:101
T max(T x_, T y_)
T min(T x_, T y_)
void Out(T t, int w, CNcbiOstream &to=cout)
Definition: parse.cpp:467
bool operator()(FPT left, FPT right, fraction_tolerance_t< ToleranceBaseType > tolerance, floating_point_comparison_type fpc_type=FPC_STRONG)
bool operator()(FPT left, FPT right, percent_tolerance_t< ToleranceBaseType > tolerance, floating_point_comparison_type fpc_type=FPC_STRONG)
Modified on Tue Dec 05 02:21:46 2023 by modify_doxy.py rev. 669887