]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/doc/fp_utilities/float_next.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / math / doc / fp_utilities / float_next.qbk
1 [section:next_float Floating-Point Representation Distance (ULP),
2 and Finding Adjacent Floating-Point Values]
3
4 [@http://en.wikipedia.org/wiki/Unit_in_the_last_place Unit of Least Precision or Unit in the Last Place]
5 is the gap between two different, but as close as possible, floating-point numbers.
6
7 Most decimal values, for example 0.1, cannot be exactly represented as floating-point values,
8 but will be stored as the
9 [@http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding
10 closest representable floating-point].
11
12 Functions are provided for finding adjacent greater and lesser floating-point values,
13 and estimating the number of gaps between any two floating-point values.
14
15 The floating-point type (FPT) must have has a fixed number of bits in the representation.
16 The number of bits may set at runtime, but must be the same for all numbers.
17 For example, __NTL_quad_float type (fixed 128-bit representation),
18 __NTL_RR type (arbitrary but fixed decimal digits, default 150) or
19 __multiprecision __cpp_dec_float and__cpp_bin_float are fixed at runtime,
20 but [*not] a type that extends the representation to provide an exact representation
21 for any number, for example [@http://keithbriggs.info/xrc.html XRC eXact Real in C].
22
23 [section:nextafter Finding the Next Representable Value in a Specific Direction (nextafter)]
24
25 [h4 Synopsis]
26
27 ``
28 #include <boost/math/special_functions/next.hpp>
29 ``
30
31 namespace boost{ namespace math{
32
33 template <class FPT>
34 FPT nextafter(FPT val, FPT direction);
35
36 }} // namespaces
37
38 [h4 Description - nextafter]
39
40 This is an implementation of the `nextafter` function included in the C99 standard.
41 (It is also effectively an implementation of the C99 `nexttoward` legacy function
42 which differs only having a `long double` direction,
43 and can generally serve in its place if required).
44
45 [note The C99 functions must use suffixes f and l to distinguish `float` and `long double` versions.
46 C++ uses the template mechanism instead.]
47
48 Returns the next representable value after /x/ in the direction of /y/. If
49 `x == y` then returns /x/. If /x/ is non-finite then returns the result of
50 a __domain_error. If there is no such value in the direction of /y/ then
51 returns an __overflow_error.
52
53 [warning The template parameter FTP must be a floating-point type.
54 An integer type, for example, will produce an unhelpful error message.]
55
56 [tip Nearly always, you just want the next or prior representable value,
57 so instead use `float_next` or `float_prior` below.]
58
59 [h4 Examples - nextafter]
60
61 The two representations using a 32-bit float either side of unity are:
62 ``
63 The nearest (exact) representation of 1.F is 1.00000000
64 nextafter(1.F, 999) is 1.00000012
65 nextafter(1/f, -999) is 0.99999994
66
67 The nearest (not exact) representation of 0.1F is 0.100000001
68 nextafter(0.1F, 10) is 0.100000009
69 nextafter(0.1F, 10) is 0.099999994
70 ``
71
72 [endsect] [/section:nextafter Finding the Next Representable Value in a Specific Direction (nextafter)]
73
74 [section:float_next Finding the Next Greater Representable Value (float_next)]
75
76 [h4 Synopsis]
77
78 ``
79 #include <boost/math/special_functions/next.hpp>
80 ``
81
82 namespace boost{ namespace math{
83
84 template <class FPT>
85 FPT float_next(FPT val);
86
87 }} // namespaces
88
89 [h4 Description - float_next]
90
91 Returns the next representable value which is greater than /x/.
92 If /x/ is non-finite then returns the result of
93 a __domain_error. If there is no such value greater than /x/ then
94 returns an __overflow_error.
95
96 Has the same effect as
97
98 nextafter(val, (std::numeric_limits<FPT>::max)());
99
100 [endsect] [/section:float_next Finding the Next Greater Representable Value (float_prior)]
101
102 [section:float_prior Finding the Next Smaller Representable Value (float_prior)]
103
104 [h4 Synopsis]
105
106 ``
107 #include <boost/math/special_functions/next.hpp>
108 ``
109
110 namespace boost{ namespace math{
111
112 template <class FPT>
113 FPT float_prior(FPT val);
114
115 }} // namespaces
116
117
118 [h4 Description - float_prior]
119
120 Returns the next representable value which is less than /x/.
121 If /x/ is non-finite then returns the result of
122 a __domain_error. If there is no such value less than /x/ then
123 returns an __overflow_error.
124
125 Has the same effect as
126
127 nextafter(val, -(std::numeric_limits<FPT>::max)()); // Note most negative value -max.
128
129 [endsect] [/section:float_prior Finding the Next Smaller Representable Value (float_prior)]
130
131 [section:float_distance Calculating the Representation Distance
132 Between Two floating-point Values (ULP) float_distance]
133
134 Function float_distance finds the number of gaps/bits/ULP between any two floating-point values.
135 If the significands of floating-point numbers are viewed as integers,
136 then their difference is the number of ULP/gaps/bits different.
137
138 [h4 Synopsis]
139
140 ``
141 #include <boost/math/special_functions/next.hpp>
142 ``
143
144 namespace boost{ namespace math{
145
146 template <class FPT>
147 FPT float_distance(FPT a, FPT b);
148
149 }} // namespaces
150
151 [h4 Description - float_distance]
152
153 Returns the distance between /a/ and /b/: the result is always
154 a signed integer value (stored in floating-point type FPT)
155 representing the number of distinct representations between /a/ and /b/.
156
157 Note that
158
159 * `float_distance(a, a)` always returns 0.
160 * `float_distance(float_next(a), a)` always returns -1.
161 * `float_distance(float_prior(a), a)` always returns 1.
162
163 The function `float_distance` is equivalent to calculating the number
164 of ULP (Units in the Last Place) between /a/ and /b/ except that it
165 returns a signed value indicating whether `a > b` or not.
166
167 If the distance is too great then it may not be able
168 to be represented as an exact integer by type FPT,
169 but in practice this is unlikely to be a issue.
170
171 [endsect] [/section:float_distance Calculating the Representation Distance
172 Between Two floating-point Values (ULP) float_distance]
173
174 [section:float_advance Advancing a floating-point Value by a Specific
175 Representation Distance (ULP) float_advance]
176
177 Function `float_advance` advances a floating-point number by a specified number
178 of ULP.
179
180 [h4 Synopsis]
181
182 ``
183 #include <boost/math/special_functions/next.hpp>
184 ``
185
186 namespace boost{ namespace math{
187
188 template <class FPT>
189 FPT float_advance(FPT val, int distance);
190
191 }} // namespaces
192
193 [h4 Description - float_advance]
194
195 Returns a floating-point number /r/ such that `float_distance(val, r) == distance`.
196
197 [endsect] [/section:float_advance]
198
199 [section:ulp Obtaining the Size of a Unit In the Last Place - ULP]
200
201 Function `ulp` gives the size of a unit-in-the-last-place for a specified floating-point value.
202
203 [h4 Synopsis]
204
205 ``
206 #include <boost/math/special_functions/ulp.hpp>
207 ``
208
209 namespace boost{ namespace math{
210
211 template <class FPT>
212 FPT ulp(const FPT& x);
213
214 template <class FPT, class Policy>
215 FPT ulp(const FPT& x, const Policy&);
216
217 }} // namespaces
218
219 [h4 Description - ulp]
220
221 Returns one [@http://en.wikipedia.org/wiki/Unit_in_the_last_place unit in the last place] of ['x].
222
223 Corner cases are handled as followes:
224
225 * If the argument is a NaN, then raises a __domain_error.
226 * If the argument is an infinity, then raises an __overflow_error.
227 * If the argument is zero then returns the smallest representable value: for example for type
228 `double` this would be either `std::numeric_limits<double>::min()` or `std::numeric_limits<double>::denorm_min()`
229 depending whether denormals are supported (which have the values 2.`2250738585072014e-308` and `4.9406564584124654e-324` respectively).
230 * If the result is too small to represent, then returns the smallest representable value.
231 * Always returns a positive value such that `ulp(x) == ulp(-x)`.
232
233 [*Important:] The behavior of this function is aligned to that of [@http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ulp%28double%29
234 Java's ulp function], please note
235 however that this function should only ever be used for rough and ready calculations as there are enough
236 corner cases to trap even careful programmers. In particular:
237
238 * The function is asymetrical, which is to say, given `u = ulp(x)` if `x > 0` then `x + u` is the
239 next floating-point value, but `x - u` is not necessarily the previous value. Similarly, if
240 `x < 0` then `x - u` is the previous floating-point value, but `x + u` is not necessarily the next
241 value. The corner cases occur at power of 2 boundaries.
242 * When the argument becomes very small, it may be that there is no floating-point value that
243 represents one ULP. Whether this is the case or not depends not only on whether the hardware
244 may ['sometimes] support denormals (as signalled by `std::numeric_limits<FPT>::has_denorm`), but also whether these are
245 currently enabled at runtime (for example on SSE hardware, the DAZ or FTZ flags will disable denormal support).
246 In this situation, the `ulp` function may return a value that is many orders of magnitude too large.
247
248 In light of the issues above, we recomend that:
249
250 * To move between adjacent floating-point values always use __float_next, __float_prior or __nextafter (`std::nextafter`
251 is another candidate, but our experience is that this also often breaks depending which optimizations and
252 hardware flags are in effect).
253 * To move several floating-point values away use __float_advance.
254 * To calculate the edit distance between two floats use __float_distance.
255
256 There is none the less, one important use case for this function:
257
258 If it is known that the true result of some function is x[sub t] and the calculated result
259 is x[sub c], then the error measured in ulp is simply [^fabs(x[sub t] - x[sub c]) / ulp(x[sub t])].
260
261 [endsect] [/section ulp]
262
263 [endsect] [/ section:next_float Floating-Point Representation Distance (ULP),
264 and Finding Adjacent Floating-Point Values]
265
266 [/
267 Copyright 2008 John Maddock and Paul A. Bristow.
268 Distributed under the Boost Software License, Version 1.0.
269 (See accompanying file LICENSE_1_0.txt or copy at
270 http://www.boost.org/LICENSE_1_0.txt).
271 ]
272