BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlb_doublecompareutil.h
Go to the documentation of this file.
1/// @file bdlb_doublecompareutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_doublecompareutil.h -*-C++-*-
8#ifndef INCLUDED_BDLB_DOUBLECOMPAREUTIL
9#define INCLUDED_BDLB_DOUBLECOMPAREUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_doublecompareutil bdlb_doublecompareutil
15/// @brief Provide "fuzzy" equality/relational operations on `double` values.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_doublecompareutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_doublecompareutil-purpose"> Purpose</a>
25/// * <a href="#bdlb_doublecompareutil-classes"> Classes </a>
26/// * <a href="#bdlb_doublecompareutil-description"> Description </a>
27/// * <a href="#bdlb_doublecompareutil-formal-definition-and-tolerances"> Formal Definition and Tolerances </a>
28/// * <a href="#bdlb_doublecompareutil-special-values-handling"> Special Values Handling </a>
29/// * <a href="#bdlb_doublecompareutil-table-demonstrating-the-results-for-comparisons"> Table Demonstrating the Results for Comparisons </a>
30/// * <a href="#bdlb_doublecompareutil-valid-use-limitations-and-caveats"> Valid Use, Limitations, and Caveats </a>
31/// * <a href="#bdlb_doublecompareutil-usage"> Usage </a>
32/// * <a href="#bdlb_doublecompareutil-example-1-meaningful-comparisons"> Example 1: Meaningful Comparisons </a>
33///
34/// # Purpose {#bdlb_doublecompareutil-purpose}
35/// Provide "fuzzy" equality/relational operations on `double` values.
36///
37/// # Classes {#bdlb_doublecompareutil-classes}
38///
39/// - bdlb::DoubleCompareUtil: namespace for "fuzzy" comparison functions
40///
41/// # Description {#bdlb_doublecompareutil-description}
42/// This component implements a utility class that performs "fuzzy"
43/// equality and relational operations as a suite of functions, each of which
44/// operates on a pair of `double` values `a` and `b`. The term "fuzzy
45/// equality" expresses the notion that `a` and `b` are "close enough", and
46/// that any difference that may exist between the values implied by the
47/// physical representations of `a` and `b` is not significant, and should be
48/// ignored for comparison purposes.
49///
50/// For example:
51/// @code
52/// bdlb::DoubleCompareUtil::fuzzyEq(a, b)
53/// @endcode
54/// This comparison returns whether values `a` and `b` are "close enough" to be
55/// considered equal. This example uses the default tolerances of
56/// `bdlb::DoubleCompareUtil` for "absolute difference" and "relative
57/// difference" (which are defined below).
58///
59/// Notice that being able ignore small differences between floating point
60/// numbers for the purpose of comparison is important, because `double`
61/// provides binary *approximations* for the mathematical concept of real
62/// numbers. Differences related to these approximation may accumulate when
63/// performing calculations such that a sequence of operations performed on two
64/// numbers, which might result in equal values for real numbers, may result in
65/// `double` approximations that are very close (but different).
66///
67/// ## Formal Definition and Tolerances {#bdlb_doublecompareutil-formal-definition-and-tolerances}
68///
69///
70/// More formally, the *absolute* *difference* between `a` and `b` is defined
71/// as the absolute value of the difference of `a` and `b`:
72/// @code
73/// fabs(a - b) // absolute difference
74/// @endcode
75/// The *relative* *difference* is defined as the quotient of the absolute
76/// difference and the absolute value of the average of `a` and `b`.
77/// @code
78/// fabs(a - b) / fabs((a + b) / 2.0) // relative difference
79/// @endcode
80/// Objects `a` and `b` have fuzzy equality if they have the same value, or if
81/// either their absolute difference is less than or equal to some
82/// user-specified (or default) tolerance value `absTol`, or their relative
83/// difference is less or equal to some separate, user-specified (or default)
84/// tolerance value `relTol`. Using the notation "A ::= B" to mean
85/// "A is defined as B", we define fuzzy equality (denoted "~eq") as follows:
86/// @code
87/// a ~eq b ::= a == b
88/// || fabs(a - b) <= absTol
89/// || fabs(a - b) / fabs((a + b) / 2.0) <= relTol
90/// @endcode
91/// where `fabs(double)` is the standard C absolute-value function and all
92/// symbols other than `~` and `::=` have their usual C++ meaning. Note that
93/// the fuzzy equality operation is symmetric (i.e., commutative) with respect
94/// to `a` and `b` for *all* values of `relTol` and `absTol`.
95///
96/// The following table identifies the six fuzzy equality and relational
97/// operations corresponding to the standard C++ operators, along with the
98/// associated static member functions defined within the
99/// `bdlb::DoubleCompareUtil` utility `struct` (note that the parameters
100/// `relTol` and `absTol` are optional, and default to reasonable,
101/// implementation-dependent values):
102/// @code
103/// C++ fuzzy
104/// operator operation qualified static member-function name
105/// -------- --------- -------------------------------------------
106/// == ~eq DoubleCompareUtil::eq(a, b, relTol, absTol)
107/// != ~ne DoubleCompareUtil::ne(a, b, relTol, absTol)
108/// < ~lt DoubleCompareUtil::lt(a, b, relTol, absTol)
109/// <= ~le DoubleCompareUtil::le(a, b, relTol, absTol)
110/// > ~gt DoubleCompareUtil::gt(a, b, relTol, absTol)
111/// >= ~ge DoubleCompareUtil::ge(a, b, relTol, absTol)
112/// @endcode
113/// Each of the other fuzzy (inequality and relational) operations is defined
114/// with respect to fuzzy equality:
115/// @code
116/// a ~ne b ::= !(a ~eq b)
117/// a ~lt b ::= !(a ~eq b) && (a < b)
118/// a ~le b ::= (a ~eq b) || (a < b)
119/// a ~gt b ::= !(a ~eq b) && (a > b)
120/// a ~ge b ::= (a ~eq b) || (a > b)
121/// @endcode
122///
123/// ## Special Values Handling {#bdlb_doublecompareutil-special-values-handling}
124///
125///
126/// Floating point numbers support infinity, NaN and negative zero values. Such
127/// values are allowed only for the `a` and `b` parameters, but not for the
128/// absolute or the relative tolerance parameters.
129///
130/// If a NaN value is specified as either (or both) compared argument (`a` or
131/// `b`) the `fuzzyCompare` method returns `e_NON_COMPARABLE`, `fuzzyNe` returns
132/// `true`, while all the other methods return `false` values as dictated by the
133/// IEEE 754 standard.
134///
135/// If infinity is provided as a value the comparisons will behave in the
136/// expected manner that positive infinity is larger than any non-infinite
137/// value, while negative infinity is smaller than any finite value. Two
138/// infinity values will compare equal if their sign is the same, otherwise the
139/// negative infinity value will be reported as less than the positive.
140///
141/// As per IEEE 754 negative zero values are considered equal to "normal" zero
142/// values. Note that negative zero values represent a minuscule negative value
143/// that could not be represented by the finite precision and exponent of a
144/// floating point representation. In other words it indicates that we have
145/// "arrived" at the zero value from the negative "side" during a calculation.
146///
147/// ## Table Demonstrating the Results for Comparisons {#bdlb_doublecompareutil-table-demonstrating-the-results-for-comparisons}
148///
149///
150/// To illustrate precise behavior, the following example tabulates the
151/// numerical results of calling the six fuzzy-comparison functions on a set of
152/// carefully selected inputs `x` and `y`, where `relTol` and `absTol` are,
153/// respectively the relative and absolute tolerances (the actual relative and
154/// absolute differences of `x` and `y`, rounded to five decimal digits, are
155/// tabulated, for reference, in the two columns to the extreme right):
156/// @code
157/// <---------INPUTS-----------> <--------OUTPUTS-----> <-ACTUAL DIFFS->
158/// x y relTol absTol eq ne lt le gt ge RelDiff AbsDiff
159/// ----- ----- ------ ------ -- -- -- -- -- -- ------- -------
160/// 99.0 100.0 0.010 0.001 0 1 1 1 0 0 0.01005 1.00000
161/// 100.0 99.0 0.010 0.001 0 1 0 0 1 1 0.01005 1.00000
162/// 99.0 100.0 0.011 0.001 1 0 0 1 0 1 0.01005 1.00000
163/// 99.0 100.0 0.010 0.999 0 1 1 1 0 0 0.01005 1.00000
164/// 99.0 100.0 0.010 1.000 1 0 0 1 0 1 0.01005 1.00000
165///
166/// 100.0 101.0 0.009 0.001 0 1 1 1 0 0 0.00995 1.00000
167/// 101.0 100.0 0.009 0.001 0 1 0 0 1 1 0.00995 1.00000
168/// 100.0 101.0 0.010 0.001 1 0 0 1 0 1 0.00995 1.00000
169/// 100.0 101.0 0.009 0.999 0 1 1 1 0 0 0.00995 1.00000
170/// 100.0 101.0 0.009 1.000 1 0 0 1 0 1 0.00995 1.00000
171/// @endcode
172///
173/// ## Valid Use, Limitations, and Caveats {#bdlb_doublecompareutil-valid-use-limitations-and-caveats}
174///
175///
176/// Each of the functions implemented in this component are well behaved for all
177/// non-negative numeric values of `relTol` and `absTol`. If either `relTol`
178/// or `absTol` is NaN, infinioty, or negative the behavior is undefined. (Note
179/// that this includes negative zero!) If either `relTol` or `absTol` is
180/// (positive) zero, that aspect of "fuzzy comparison" is suppressed; if both
181/// are zero, each of the six fuzzy-comparison operations behave as
182/// runtime-intensive versions of their non-fuzzy counterparts.
183///
184/// Note that the definition of fuzzy equality used in this component does have
185/// one intermediate singularity: When `(fabs(a - b) > absTol && (a == -b))` is
186/// true, the pseudo-expression `a ~eq b` defined above has a zero denominator.
187/// In this case, the test for relative fuzzy equality is suppressed. This
188/// intermediate singularity does not, however, lead to a special-case behavior
189/// of fuzzy comparisons: By definition, the relative difference is the quotient
190/// of the absolute difference and the absolute average, so the case `(a == -b)`
191/// truly represents an "infinite relative difference", and thus fuzzy equality
192/// via the relative difference criteria should be false (although absolute
193/// fuzzy equality may still prevail).
194///
195/// Finally, note that the implementations of the functions in this component
196/// are vulnerable to the limitations of values that can be represented by
197/// a `double`. In particular, if `(a + b)` or `(a - b)` cannot be represented,
198/// the functions will fail outright. More subtly, as `a` or `b` approaches the
199/// limits of precision of representation, the algorithms used in this component
200/// become increasingly unreliable. The user is responsible for determining
201/// the limits of applicability of this component to a given calculation, and
202/// for coding accordingly.
203///
204/// ## Usage {#bdlb_doublecompareutil-usage}
205///
206///
207/// This section illustrates intended use of this component.
208///
209/// ### Example 1: Meaningful Comparisons {#bdlb_doublecompareutil-example-1-meaningful-comparisons}
210///
211///
212/// The `bdlb::DoubleCompareUtil` utility functions are well suited for
213/// comparing both final or intermediate values such as prices, volumes,
214/// interest rates, and the products and quotients thereof. We'll now
215/// illustrate the use of some of the various `bdlb::DoubleCompareUtil`
216/// comparison methods on two `double` values `a` and `b`. First we'll
217/// determine whether the two values are "CLOSE ENOUGH" using the
218/// implementation-defined (default) tolerances:
219/// @code
220/// if (bdlb::DoubleCompareUtil::fuzzyEq(a, b)) {
221/// bsl::cout << "Values `a` and `b` are CLOSE ENOUGH.\n";
222/// }
223/// @endcode
224/// Next, we'll determine whether the same two values are "NOT RELATIVELY CLOSE"
225/// using our own (unusually large) criteria of 1.0 for relative tolerance, but
226/// continuing to rely on the default value for absolute tolerance:
227/// @code
228/// if (bdlb::DoubleCompareUtil::fuzzyNe(a, b, 1.0)) {
229/// bsl::cout << "Values `a` and `b` are NOT RELATIVELY CLOSE.\n";
230/// }
231/// @endcode
232/// Finally, we'll determine if the value `a` is "SIGNIFICANTLY GREATER THAN"
233/// `b` by supplying our own rather larger values of 1e-1 and 1e-3 for the
234/// relative and absolute tolerances, respectively:
235/// @code
236/// if (bdlb::DoubleCompareUtil::fuzzyGt(a, b, 1e-1, 1e-3)) {
237/// bsl::cout << "Value `a` is SIGNIFICANTLY GREATER THAN `b`.\n";
238/// }
239/// @endcode
240/// Which will print to `bsl::cout` if and only if:
241/// @code
242/// bdlb::DoubleCompareUtil::fuzzyNe(a, b, 1e-1, 1e-3) && a > b
243/// @endcode
244/// is `true`.
245/// @}
246/** @} */
247/** @} */
248
249/** @addtogroup bdl
250 * @{
251 */
252/** @addtogroup bdlb
253 * @{
254 */
255/** @addtogroup bdlb_doublecompareutil
256 * @{
257 */
258
259#include <bdlscm_version.h>
260
261
262namespace bdlb {
263
264 // ==============================
265 // struct bdlb::DoubleCompareUtil
266 // ==============================
267
268/// This struct provides a namespace for a suite of fuzzy (equality
269/// and relational) comparison functions on pairs of `double` values,
270/// parameterized by (optionally specified) relative and absolute tolerances.
271///
272/// \note Note that all methods are naturally thread-safe, and
273/// well-behaved for all tolerance values.
274///
275/// See @ref bdlb_doublecompareutil
277 public:
278 // PUBLIC TYPES
285
286 public:
287 // PUBLIC CONSTANTS
288 static const double k_DEFAULT_RELATIVE_TOLERANCE;
289 static const double k_DEFAULT_ABSOLUTE_TOLERANCE;
290
291 public:
292 // CLASS METHODS
293
294 /// Return `e_EQUAL` if the specified `a` and `b` have fuzzy equality,
295 /// `e_GREATER_THAN` if `a > b`, `e_LESS_THAN` if `a < b`, and
296 /// `e_NON_COMPARABLE` if either `a` or `b` are a NaN. Optionally specify
297 /// the relative tolerance `relTol`, or `relTol` and the absolute tolerance
298 /// `absTol`, used to determine fuzzy equality. If an optional tolerance
299 /// argument is not specified, a reasonable (implementation-dependent)
300 /// default value for that tolerance is used. Fuzzy equality (denoted
301 /// "a ~eq b") between `a` and `b` is defined in terms of the relative
302 /// tolerance `relTol` and the absolute tolerance `absTol` such that the
303 /// expression:
304 /// @code
305 /// a == b || fabs(a - b) <= absTol
306 /// || fabs(a - b) / fabs((a + b) / 2.0) <= relTol
307 /// @endcode
308 /// is `true`; however, in the special case where `a != 0 && a == -b`
309 /// is `true`, the actual relative difference is effectively infinite,
310 /// and no value of `relTol` can imply fuzzy equality (although a sufficiently large value of `absTol` can).
311 ///
312 /// \note Note that if either
313 /// `absTol` or `relTol` is 0.0, that aspect of fuzzy comparison is
314 /// effectively suppressed, but the behavior of this function is defined.
315 ///
316 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are
317 /// non-negative, finite numbers (which excludes NaN and infinity). Note
318 /// also that the primary purpose of this public static comparison method
319 /// is to implement the six fuzzy equality and relational functions also
320 /// defined within this utility `struct` (see `fuzzyEq`, `fuzzyNe`,
321 /// `fuzzyLt`, `fuzzyLe`, `fuzzyGt`, and `fuzzyGe`).
322 static CompareResult fuzzyCompare(double a, double b);
323 static CompareResult fuzzyCompare(double a, double b, double relTol);
325 double b,
326 double relTol,
327 double absTol);
328
329 /// Return `true` if the specified `a` and `b` satisfy the fuzzy
330 /// equality relation (denoted "a ~eq b") as defined by the expression:
331 /// @code
332 /// fuzzyCompare(a, b, relTol, absTol) == e_EQUAL
333 /// @endcode
334 /// and `false` otherwise. Optionally specify the relative tolerance
335 /// `relTol`, or `relTol` and the absolute tolerance `absTol`, used to
336 /// determine fuzzy equality. If an optional tolerance argument is
337 /// not specified, a reasonable (implementation-dependent) default value for that tolerance is used.
338 ///
339 /// \note Note that if either `absTol` or
340 /// `relTol` is 0.0, that aspect of fuzzy comparison is effectively
341 /// suppressed, but the behavior of this function is defined.
342 ///
343 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are non-negative, finite
344 /// numbers (which excludes NaN and infinity).
345 static bool fuzzyEq(double a, double b);
346 static bool fuzzyEq(double a, double b, double relTol);
347 static bool fuzzyEq(double a, double b, double relTol, double absTol);
348
349 /// Return `true` if the specified `a` and `b` satisfy the fuzzy
350 /// inequality relation (denoted "a ~ne b") as defined by the
351 /// expression:
352 /// @code
353 /// fuzzyCompare(a, b, relTol, absTol) != e_EQUAL
354 /// @endcode
355 /// and `false` otherwise. Optionally specify the relative tolerance
356 /// `relTol`, or `relTol` and the absolute tolerance `absTol`, used to
357 /// determine fuzzy inequality. If an optional tolerance argument is
358 /// not specified, a reasonable (implementation-dependent) default value for that tolerance is used.
359 ///
360 /// \note Note that if either `absTol` or
361 /// `relTol` is 0.0, that aspect of fuzzy comparison is effectively
362 /// suppressed, but the behavior of this function is defined.
363 ///
364 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are non-negative, finite
365 /// numbers (which excludes NaN and infinity).
366 static bool fuzzyNe(double a, double b);
367 static bool fuzzyNe(double a, double b, double relTol);
368 static bool fuzzyNe(double a, double b, double relTol, double absTol);
369
370 /// Return `true` if the specified `a` and `b` satisfy the fuzzy
371 /// less-than relation (denoted "a ~lt b") as defined by the expression:
372 /// @code
373 /// fuzzyCompare(a, b, relTol, absTol) == e_LESS_THAN
374 /// @endcode
375 /// and `false` otherwise. Optionally specify the relative tolerance
376 /// `relTol`, or `relTol` and the absolute tolerance `absTol`, used to
377 /// determine fuzzy less-than. If an optional tolerance argument is
378 /// not specified, a reasonable (implementation-dependent) default value for that tolerance is used.
379 ///
380 /// \note Note that if either `absTol` or
381 /// `relTol` is 0.0, that aspect of fuzzy comparison is effectively
382 /// suppressed, but the behavior of this function is defined.
383 ///
384 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are non-negative, finite
385 /// numbers (which excludes NaN and infinity).
386 static bool fuzzyLt(double a, double b);
387 static bool fuzzyLt(double a, double b, double relTol);
388 static bool fuzzyLt(double a, double b, double relTol, double absTol);
389
390 /// Return `true` if the specified `a` and `b` satisfy the fuzzy
391 /// less-equal relation (denoted "a ~le b") as defined by the
392 /// expression:
393 /// @code
394 /// fuzzyCompare(a, b, relTol, absTol) == e_LESS_THAN or == e_EQUAL
395 /// @endcode
396 /// and `false` otherwise. Optionally specify the relative tolerance
397 /// `relTol`, or `relTol` and the absolute tolerance `absTol`, used to
398 /// determine fuzzy less-equal. If an optional tolerance argument is
399 /// not specified, a reasonable (implementation-dependent) default value for that tolerance is used.
400 ///
401 /// \note Note that if either `absTol` or
402 /// `relTol` is 0.0, that aspect of fuzzy comparison is effectively
403 /// suppressed, but the behavior of this function is defined.
404 ///
405 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are non-negative, finite
406 /// numbers (which excludes NaN and infinity).
407 static bool fuzzyLe(double a, double b);
408 static bool fuzzyLe(double a, double b, double relTol);
409 static bool fuzzyLe(double a, double b, double relTol, double absTol);
410
411 /// Return `true` if the specified `a` and `b` satisfy the fuzzy
412 /// greater-than relation (denoted "a ~lt b") as defined by the
413 /// expression:
414 /// @code
415 /// fuzzyCompare(a, b, relTol, absTol) == e_GREATER_THAN
416 /// @endcode
417 /// and `false` otherwise. Optionally specify the relative tolerance
418 /// `relTol`, or `relTol` and the absolute tolerance `absTol`, used to
419 /// determine fuzzy greater-than. If an optional tolerance argument is
420 /// not specified, a reasonable (implementation-dependent) default value for that tolerance is used.
421 ///
422 /// \note Note that if either `absTol` or
423 /// `relTol` is 0.0, that aspect of fuzzy comparison is effectively
424 /// suppressed, but the behavior of this function is defined.
425 ///
426 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are non-negative, finite
427 /// numbers (which excludes NaN and infinity).
428 static bool fuzzyGt(double a, double b);
429 static bool fuzzyGt(double a, double b, double relTol);
430 static bool fuzzyGt(double a, double b, double relTol, double absTol);
431
432 /// Return `true` if the specified `a` and `b` satisfy the fuzzy
433 /// greater-equal relation (denoted "a ~ge b") as defined by the
434 /// expression:
435 /// @code
436 /// fuzzyCompare(a, b, relTol, absTol) == e_GREATER_THAN or == e_EQUAL
437 /// @endcode
438 /// and `false` otherwise. Optionally specify the relative tolerance
439 /// `relTol`, or `relTol` and the absolute tolerance `absTol`, used to
440 /// determine fuzzy greater-equal. If an optional tolerance argument
441 /// is not specified, a reasonable (implementation-dependent) default value for that tolerance is used.
442 ///
443 /// \note Note that if either `absTol` or
444 /// `relTol` is 0.0, that aspect of fuzzy comparison is effectively
445 /// suppressed, but the behavior of this function is defined.
446 ///
447 /// \pre The behavior is undefined unless both 'relTol` and `absTol` are non-negative, finite
448 /// numbers (which excludes NaN and infinity).
449 static bool fuzzyGe(double a, double b);
450 static bool fuzzyGe(double a, double b, double relTol);
451 static bool fuzzyGe(double a, double b, double relTol, double absTol);
452};
453
454// ============================================================================
455// INLINE FUNCTION DEFINITIONS
456// ============================================================================
457
458 // ------------------------------
459 // struct bdlb::DoubleCompareUtil
460 // ------------------------------
461
462// CLASS METHODS
463inline
472
473inline
475DoubleCompareUtil::fuzzyCompare(double a, double b, double relTol)
476{
477 return fuzzyCompare(a, b, relTol, k_DEFAULT_ABSOLUTE_TOLERANCE);
478}
479
480inline
481bool DoubleCompareUtil::fuzzyEq(double a, double b)
482{
483 return fuzzyCompare(a,
484 b,
487}
488
489inline
490bool DoubleCompareUtil::fuzzyEq(double a, double b, double relTol)
491{
492 return fuzzyCompare(a, b, relTol, k_DEFAULT_ABSOLUTE_TOLERANCE) == e_EQUAL;
493}
494
495inline
496bool
497DoubleCompareUtil::fuzzyEq(double a, double b, double relTol, double absTol)
498{
499 return fuzzyCompare(a, b, relTol, absTol) == e_EQUAL;
500}
501
502inline
503bool DoubleCompareUtil::fuzzyNe(double a, double b)
504{
505 return fuzzyCompare(a,
506 b,
509}
510
511inline
512bool DoubleCompareUtil::fuzzyNe(double a, double b, double relTol)
513{
514 return fuzzyCompare(a, b, relTol, k_DEFAULT_ABSOLUTE_TOLERANCE) != e_EQUAL;
515}
516
517inline
518bool
519DoubleCompareUtil::fuzzyNe(double a, double b, double relTol, double absTol)
520{
521 return fuzzyCompare(a, b, relTol, absTol) != e_EQUAL;
522}
523
524inline
525bool DoubleCompareUtil::fuzzyLt(double a, double b)
526{
527 return fuzzyCompare(a,
528 b,
531}
532
533inline
534bool DoubleCompareUtil::fuzzyLt(double a, double b, double relTol)
535{
536 return fuzzyCompare(a,
537 b,
538 relTol,
540}
541
542inline
543bool
544DoubleCompareUtil::fuzzyLt(double a, double b, double relTol, double absTol)
545{
546 return fuzzyCompare(a, b, relTol, absTol) == e_LESS_THAN;
547}
548
549inline
550bool DoubleCompareUtil::fuzzyLe(double a, double b)
551{
552 const CompareResult rv = fuzzyCompare(a,
553 b,
556
557 return rv == e_LESS_THAN || rv == e_EQUAL;
558}
559
560inline
561bool DoubleCompareUtil::fuzzyLe(double a, double b, double relTol)
562{
563 const CompareResult rv =
565
566 return rv == e_LESS_THAN || rv == e_EQUAL;
567}
568
569inline
570bool
571DoubleCompareUtil::fuzzyLe(double a, double b, double relTol, double absTol)
572{
573 const CompareResult rv = fuzzyCompare(a, b, relTol, absTol);
574
575 return rv == e_LESS_THAN || rv == e_EQUAL;
576}
577
578inline
579bool DoubleCompareUtil::fuzzyGt(double a, double b)
580{
581 return fuzzyCompare(a,
582 b,
585}
586
587inline
588bool DoubleCompareUtil::fuzzyGt(double a, double b, double relTol)
589{
590 return fuzzyCompare(a,
591 b,
592 relTol,
594}
595
596inline
597bool
598DoubleCompareUtil::fuzzyGt(double a, double b, double relTol, double absTol)
599{
600 return fuzzyCompare(a, b, relTol, absTol) == e_GREATER_THAN;
601}
602
603inline
604bool DoubleCompareUtil::fuzzyGe(double a, double b)
605{
606 const CompareResult rv = fuzzyCompare(a,
607 b,
610
611 return rv == e_GREATER_THAN || rv == e_EQUAL;
612}
613
614inline
615bool DoubleCompareUtil::fuzzyGe(double a, double b, double relTol)
616{
617 const CompareResult rv = fuzzyCompare(a,
618 b,
619 relTol,
621
622 return rv == e_GREATER_THAN || rv == e_EQUAL;
623}
624
625inline
626bool
627DoubleCompareUtil::fuzzyGe(double a, double b, double relTol, double absTol)
628{
629 const CompareResult rv = fuzzyCompare(a, b, relTol, absTol);
630
631 return rv == e_GREATER_THAN || rv == e_EQUAL;
632}
633
634} // close package namespace
635} // close corporate namespace
636
637#endif
638
639// ----------------------------------------------------------------------------
640// Copyright 2024 Bloomberg Finance L.P.
641//
642// Licensed under the Apache License, Version 2.0 (the "License");
643// you may not use this file except in compliance with the License.
644// You may obtain a copy of the License at
645//
646// http://www.apache.org/licenses/LICENSE-2.0
647//
648// Unless required by applicable law or agreed to in writing, software
649// distributed under the License is distributed on an "AS IS" BASIS,
650// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
651// See the License for the specific language governing permissions and
652// limitations under the License.
653// ----------------------------- END-OF-FILE ----------------------------------
654
655/** @} */
656/** @} */
657/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlb_algorithmworkaroundutil.h:74
Definition bdlb_doublecompareutil.h:276
static bool fuzzyGt(double a, double b)
Definition bdlb_doublecompareutil.h:579
static bool fuzzyLt(double a, double b)
Definition bdlb_doublecompareutil.h:525
static bool fuzzyLe(double a, double b)
Definition bdlb_doublecompareutil.h:550
CompareResult
Definition bdlb_doublecompareutil.h:279
@ e_GREATER_THAN
Definition bdlb_doublecompareutil.h:281
@ e_EQUAL
Definition bdlb_doublecompareutil.h:280
@ e_LESS_THAN
Definition bdlb_doublecompareutil.h:282
@ e_NON_COMPARABLE
Definition bdlb_doublecompareutil.h:283
static CompareResult fuzzyCompare(double a, double b, double relTol, double absTol)
static bool fuzzyNe(double a, double b)
Definition bdlb_doublecompareutil.h:503
static bool fuzzyEq(double a, double b)
Definition bdlb_doublecompareutil.h:481
static const double k_DEFAULT_RELATIVE_TOLERANCE
Definition bdlb_doublecompareutil.h:288
static const double k_DEFAULT_ABSOLUTE_TOLERANCE
Definition bdlb_doublecompareutil.h:289
static bool fuzzyGe(double a, double b)
Definition bdlb_doublecompareutil.h:604
static CompareResult fuzzyCompare(double a, double b)
Definition bdlb_doublecompareutil.h:465