]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/doc/fp_utilities/float_comparison.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / math / doc / fp_utilities / float_comparison.qbk
1 [section:float_comparison Floating-point Comparison]
2
3 [import ../../example/float_comparison_example.cpp]
4
5 Comparison of floating-point values has always been a source of endless difficulty and confusion.
6
7 Unlike integral values that are exact, all floating-point operations
8 will potentially produce an inexact result that will be rounded to the nearest
9 available binary representation. Even apparently inocuous operations such as assigning
10 0.1 to a double produces an inexact result (as this decimal number has no
11 exact binary representation).
12
13 Floating-point computations also involve rounding so that some 'computational noise' is added,
14 and hence results are also not exact (although repeatable, at least under identical platforms and compile options).
15
16 Sadly, this conflicts with the expectation of most users, as many articles and innumerable cries for help show all too well.
17
18 Some background reading is:
19
20 * Knuth D.E. The art of computer programming, vol II, section 4.2, especially Floating-Point Comparison 4.2.2, pages 198-220.
21 * [@http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html David Goldberg, "What Every Computer Scientist Should Know About Floating-Point Arithmetic"]
22 * [@http://adtmag.com/articles/2000/03/16/comparing-floatshow-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been-r.aspx
23 Alberto Squassabia, Comparing floats listing]
24 * [@https://code.google.com/p/googletest/wiki/AdvancedGuide#Floating-Point_Comparison Google Floating-Point_Comparison guide]
25 * [@boost:/libs/test/doc/html/boost_test/users_guide/testing_tools/testing_floating_points.html Boost.Test Floating-Point_Comparison]
26
27 Boost provides a number of ways to compare floating-point values to see if they are tolerably close enough to each other,
28 but first we must decide what kind of comparison we require:
29
30 * Absolute difference/error: the absolute difference between two values ['a] and ['b] is simply `fabs(a-b)`.
31 This is the only meaningful comparison to make if we know that the result may have cancellation error (see below).
32 * The edit distance between the two values: i.e. how many (binary) floating-point values are between two values ['a] and ['b]?
33 This is provided by the function __float_distance, but is probably only useful when you know that the distance should be very small.
34 This function is somewhat difficult to compute, and doesn't scale to values that are very far apart. In other words, use with care.
35 * The relative distance/error between two values. This is quick and easy to compute, and is generally the method of choice when
36 checking that your results are "tolerably close" to one another. However, it is not as exact as the edit distance when dealing
37 with small differences, and due to the way floating-point values are encoded can "wobble" by a factor of 2 compared to the "true"
38 edit distance. This is the method documented below: if `float_distance` is a surgeon's scalpel, then `relative_difference` is more
39 like a Swiss army knife: both have important but different use cases.
40
41
42 [h5:fp_relative Relative Comparison of Floating-point Values]
43
44
45 `#include <boost/math/special_functions/relative_difference.hpp>`
46
47 template <class T, class U>
48 ``__sf_result`` relative_difference(T a, U b);
49
50 template <class T, class U>
51 ``__sf_result`` epsilon_difference(T a, U b);
52
53 The function `relative_difference` returns the relative distance/error ['E] between two values as defined by:
54
55 [pre E = fabs((a - b) / min(a,b))]
56
57 The function `epsilon_difference` is a convenience function that returns `relative_difference(a, b) / eps` where
58 `eps` is the machine epsilon for the result type.
59
60 The following special cases are handled as follows:
61
62 * If either of ['a] or ['b] is a NaN, then returns the largest representable value for T: for example for type `double`, this
63 is `std::numeric_limits<double>::max()` which is the same as `DBL_MAX` or `1.7976931348623157e+308`.
64 * If ['a] and ['b] differ in sign then returns the largest representable value for T.
65 * If both ['a] and ['b] are both infinities (of the same sign), then returns zero.
66 * If just one of ['a] and ['b] is an infinity, then returns the largest representable value for T.
67 * If both ['a] and ['b] are zero then returns zero.
68 * If just one of ['a] or ['b] is a zero or a denormalized value, then it is treated as if it were the
69 smallest (non-denormalized) value representable in T for the purposes of the above calculation.
70
71 These rules were primarily designed to assist with our own test suite, they are designed to be robust enough
72 that the function can in most cases be used blindly, including in cases where the expected result is actually
73 too small to represent in type T and underflows to zero.
74
75 [h5 Examples]
76
77 [compare_floats_using]
78
79 [compare_floats_example_1]
80 [compare_floats_example_2]
81 [compare_floats_example_3]
82 [compare_floats_example_4]
83 [compare_floats_example_5]
84 [compare_floats_example_6]
85
86 All the above examples are contained in [@../../example/float_comparison_example.cpp float_comparison_example.cpp].
87
88 [h5:small Handling Absolute Errors]
89
90 Imagine we're testing the following function:
91
92 double myspecial(double x)
93 {
94 return sin(x) - sin(4 * x);
95 }
96
97 This function has multiple roots, some of which are quite predicable in that both
98 `sin(x)` and `sin(4x)` are zero together. Others occur because the values returned
99 from those two functions precisely cancel out. At such points the relative difference
100 between the true value of the function and the actual value returned may be ['arbitrarily
101 large] due to [@http://en.wikipedia.org/wiki/Loss_of_significance cancellation error].
102
103 In such a case, testing the function above by requiring that the values returned by
104 `relative_error` or `epsilon_error` are below some threshold is pointless: the best
105 we can do is to verify that the ['absolute difference] between the true
106 and calculated values is below some threshold.
107
108 Of course, determining what that threshold should be is often tricky,
109 but a good starting point would be machine epsilon multiplied by the largest
110 of the values being summed. In the example above, the largest value returned
111 by `sin(whatever)` is 1, so simply using machine epsilon as the target for
112 maximum absolute difference might be a good start (though in practice we may need
113 a slightly higher value - some trial and error will be necessary).
114
115 [endsect] [/section:float_comparison Floating-point comparison]
116
117 [/
118 Copyright 2015 John Maddock and Paul A. Bristow.
119 Distributed under the Boost Software License, Version 1.0.
120 (See accompanying file LICENSE_1_0.txt or copy at
121 http://www.boost.org/LICENSE_1_0.txt).
122 ]