]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [section:error_handling Error Handling] |
2 | ||
3 | [def __format [@../../../format/index.html Boost.Format]] | |
4 | ||
5 | [heading Quick Reference] | |
6 | ||
7 | Handling of errors by this library is split into two orthogonal parts: | |
8 | ||
9 | * What kind of error has been raised? | |
10 | * What should be done when the error is raised? | |
11 | ||
12 | [warning The default error actions are to throw an exception with an informative error message. | |
13 | If you do not try to catch the exception, you will not see the message!] | |
14 | ||
15 | The kinds of errors that can be raised are: | |
16 | ||
17 | [variablelist | |
18 | [[Domain Error][Occurs when one or more arguments to a function | |
19 | are out of range.]] | |
20 | [[Pole Error][Occurs when the particular arguments cause the function to be | |
21 | evaluated at a pole with no well defined residual value. For example if | |
22 | __tgamma is evaluated at exactly -2, the function approaches different limiting | |
23 | values depending upon whether you approach from just above or just below | |
24 | -2. Hence the function has no well defined value at this point and a | |
25 | Pole Error will be raised.]] | |
26 | [[Overflow Error][Occurs when the result is either infinite, or too large | |
27 | to represent in the numeric type being returned by the function.]] | |
28 | [[Underflow Error][Occurs when the result is not zero, but is too small | |
29 | to be represented by any other value in the type being returned by | |
30 | the function.]] | |
31 | [[Denormalisation Error][Occurs when the returned result would be a denormalised value.]] | |
32 | [[Rounding Error][Occurs when the argument to one of the rounding functions __trunc, | |
33 | __round and __modf can not be represented as an integer type, is | |
34 | outside the range of the result type.]] | |
35 | [[Evaluation Error][Occurs if no method of evaluation is known, | |
36 | or when an internal error occurred that prevented the | |
37 | result from being evaluated: this should never occur, but if it does, then | |
38 | it's likely to be due to an iterative method not converging fast enough.]] | |
39 | [[Indeterminate Result Error][Occurs when the result of a function is not | |
40 | defined for the values that were passed to it.]] | |
41 | ] | |
42 | ||
43 | The action undertaken by each error condition is determined by the current | |
44 | __Policy in effect. This can be changed program-wide by setting some | |
45 | configuration macros, or at namespace scope, or at the call site (by | |
46 | specifying a specific policy in the function call). | |
47 | ||
48 | The available actions are: | |
49 | ||
50 | [variablelist | |
51 | [[throw_on_error][Throws the exception most appropriate to the error condition.]] | |
52 | [[errno_on_error][Sets ::errno to an appropriate value, and then returns the most | |
53 | appropriate result]] | |
54 | [[ignore_error][Ignores the error and simply the returns the most appropriate result.]] | |
55 | [[user_error][Calls a | |
56 | [link math_toolkit.pol_tutorial.user_def_err_pol user-supplied error handler].]] | |
57 | ] | |
58 | ||
59 | The following tables show all the permutations of errors and actions, | |
60 | with the *default action for each error shown in bold*: | |
61 | ||
62 | [table Possible Actions for Domain Errors | |
63 | [[Action] [Behaviour]] | |
64 | [[throw_on_error][[*Throws `std::domain_error`]]] | |
65 | [[errno_on_error][Sets `::errno` to `EDOM` and returns `std::numeric_limits<T>::quiet_NaN()`]] | |
66 | [[ignore_error][Returns `std::numeric_limits<T>::quiet_NaN()`]] | |
67 | [[user_error][Returns the result of `boost::math::policies::user_domain_error`: | |
68 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
69 | this function must be defined by the user].]] | |
70 | ] | |
71 | ||
72 | [table Possible Actions for Pole Errors | |
73 | [[Action] [Behaviour]] | |
74 | [[throw_on_error] [[*Throws `std::domain_error`]]] | |
75 | [[errno_on_error][Sets `::errno` to `EDOM` and returns `std::numeric_limits<T>::quiet_NaN()`]] | |
76 | [[ignore_error][Returns `std::numeric_limits<T>::quiet_NaN()`]] | |
77 | [[user_error][Returns the result of `boost::math::policies::user_pole_error`: | |
78 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
79 | this function must be defined by the user].]] | |
80 | ] | |
81 | ||
82 | [table Possible Actions for Overflow Errors | |
83 | [[Action] [Behaviour]] | |
84 | [[throw_on_error][[*Throws `std::overflow_error`]]] | |
85 | [[errno_on_error][Sets `::errno` to `ERANGE` and returns `std::numeric_limits<T>::infinity()`]] | |
86 | [[ignore_error][Returns `std::numeric_limits<T>::infinity()`]] | |
87 | [[user_error][Returns the result of `boost::math::policies::user_overflow_error`: | |
88 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
89 | this function must be defined by the user].]] | |
90 | ] | |
91 | ||
92 | [table Possible Actions for Underflow Errors | |
93 | [[Action] [Behaviour]] | |
94 | [[throw_on_error][Throws `std::underflow_error`]] | |
95 | [[errno_on_error][Sets `::errno` to `ERANGE` and returns 0.]] | |
96 | [[ignore_error][[*Returns 0]]] | |
97 | [[user_error][Returns the result of `boost::math::policies::user_underflow_error`: | |
98 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
99 | this function must be defined by the user].]] | |
100 | ] | |
101 | ||
102 | [table Possible Actions for Denorm Errors | |
103 | [[Action] [Behaviour]] | |
104 | [[throw_on_error][Throws `std::underflow_error`]] | |
105 | [[errno_on_error][Sets `::errno` to `ERANGE` and returns the denormalised value.]] | |
106 | [[ignore_error][[*Returns the denormalised value.]]] | |
107 | [[user_error][Returns the result of `boost::math::policies::user_denorm_error`: | |
108 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
109 | this function must be defined by the user].]] | |
110 | ] | |
111 | ||
112 | [table Possible Actions for Rounding Errors | |
113 | [[Action] [Behaviour]] | |
114 | [[throw_on_error][Throws `boost::math::rounding_error`]] | |
115 | [[errno_on_error][Sets `::errno` to `ERANGE` and returns the largest representable value of the target integer type | |
116 | (or the most negative value if the argument to the function was less than zero).]] | |
117 | [[ignore_error][[*Returns the largest representable value of the target integer type | |
118 | (or the most negative value if the argument to the function was less than zero).]]] | |
119 | [[user_error][Returns the result of `boost::math::policies::user_rounding_error`: | |
120 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
121 | this function must be defined by the user].]] | |
122 | ] | |
123 | ||
124 | [table Possible Actions for Internal Evaluation Errors | |
125 | [[Action] [Behaviour]] | |
126 | [[throw_on_error][[*Throws `boost::math::evaluation_error`]]] | |
127 | [[errno_on_error][Sets `::errno` to `EDOM` and returns the closest approximation found.]] | |
128 | [[ignore_error][Returns the closest approximation found.]] | |
129 | [[user_error][Returns the result of `boost::math::policies::user_evaluation_error`: | |
130 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
131 | this function must be defined by the user].]] | |
132 | ] | |
133 | ||
134 | [table Possible Actions for Indeterminate Result Errors | |
135 | [[Action] [Behaviour]] | |
136 | [[throw_on_error][Throws `std::domain_error`]] | |
137 | [[errno_on_error][Sets `::errno` to `EDOM` and returns the same value as `ignore_error`.]] | |
138 | [[ignore_error][[*Returns a default result that depends on the function where the error occurred.]]] | |
139 | [[user_error][Returns the result of `boost::math::policies::user_indeterminate_result_error`: | |
140 | [link math_toolkit.pol_tutorial.user_def_err_pol | |
141 | this function must be defined by the user].]] | |
142 | ] | |
143 | ||
144 | All these error conditions are in namespace boost::math::policies, | |
145 | made available, for example, a by namespace declaration | |
146 | using `namespace boost::math::policies;` or individual using declarations | |
147 | `using boost::math::policies::overflow_error;`. | |
148 | ||
149 | [heading Rationale] | |
150 | ||
151 | The flexibility of the current implementation should be reasonably obvious: the | |
152 | default behaviours were chosen based on feedback during the formal review of | |
153 | this library. It was felt that: | |
154 | ||
155 | * Genuine errors should be flagged with exceptions | |
156 | rather than following C-compatible behaviour and setting `::errno`. | |
157 | * Numeric underflow and denormalised results were not considered to be | |
158 | fatal errors in most cases, so it was felt that these should be ignored. | |
159 | * If there is more than one error, | |
160 | only the first detected will be reported in the throw message. | |
161 | ||
162 | [heading Finding More Information] | |
163 | ||
164 | There are some pre-processor macro defines that can be used to | |
165 | [link math_toolkit.pol_ref.policy_defaults | |
166 | change the policy defaults]. See also the [link policy | |
167 | policy section]. | |
168 | ||
169 | An example is at the Policy tutorial in | |
170 | [link math_toolkit.pol_tutorial.changing_policy_defaults | |
171 | Changing the Policy Defaults]. | |
172 | ||
173 | Full source code of this typical example of passing a 'bad' argument | |
174 | (negative degrees of freedom) to Student's t distribution | |
175 | is [link math_toolkit.stat_tut.weg.error_eg in the error handling example]. | |
176 | ||
177 | The various kind of errors are described in more detail below. | |
178 | ||
179 | [heading:domain_error Domain Errors] | |
180 | ||
181 | When a special function is passed an argument that is outside the range | |
182 | of values for which that function is defined, then the function returns | |
183 | the result of: | |
184 | ||
185 | boost::math::policies::raise_domain_error<T>(FunctionName, Message, Val, __Policy); | |
186 | ||
187 | Where | |
188 | `T` is the floating-point type passed to the function, `FunctionName` is the | |
189 | name of the function, `Message` is an error message describing the problem, | |
190 | Val is the value that was out of range, and __Policy is the current policy | |
191 | in use for the function that was called. | |
192 | ||
193 | The default policy behaviour of this function is to throw a | |
194 | std::domain_error C++ exception. But if the __Policy is to ignore | |
195 | the error, or set global `::errno`, then a NaN will be returned. | |
196 | ||
197 | This behaviour is chosen to assist compatibility with the behaviour of | |
198 | ['ISO/IEC 9899:1999 Programming languages - C] | |
199 | and with the | |
200 | [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Draft Technical Report on C++ Library Extensions, 2005-06-24, section 5.2.1, paragraph 6]: | |
201 | ||
202 | [:['"Each of the functions declared above shall return a NaN (Not a Number) | |
203 | if any argument value is a NaN, but it shall not report a domain error. | |
204 | Otherwise, each of the functions declared above shall report a domain error | |
205 | for just those argument values for which:]] | |
206 | ||
207 | [:['"the function description's Returns clause explicitly specifies a domain, and those arguments fall outside the specified domain; or] | |
208 | ||
209 | ['"the corresponding mathematical function value has a non-zero imaginary component; or] | |
210 | ||
211 | ['"the corresponding mathematical function is not mathematically defined.]] | |
212 | ||
213 | [:['"Note 2: A mathematical function is mathematically defined | |
214 | for a given set of argument values if it is explicitly defined | |
215 | for that set of argument values or | |
216 | if its limiting value exists and does not depend on the direction of approach."]] | |
217 | ||
218 | Note that in order to support information-rich error messages when throwing | |
219 | exceptions, `Message` must contain | |
220 | a __format recognised format specifier: the argument `Val` is inserted into | |
221 | the error message according to the specifier used. | |
222 | ||
223 | For example if `Message` contains a "%1%" then it is replaced by the value of | |
224 | `Val` to the full precision of T, where as "%.3g" would contain the value of | |
225 | `Val` to 3 digits. See the __format documentation for more details. | |
226 | ||
227 | [heading:pole_error Evaluation at a pole] | |
228 | ||
229 | When a special function is passed an argument that is at a pole | |
230 | without a well defined residual value, then the function returns | |
231 | the result of: | |
232 | ||
233 | boost::math::policies::raise_pole_error<T>(FunctionName, Message, Val, __Policy); | |
234 | ||
235 | Where | |
236 | `T` is the floating point type passed to the function, `FunctionName` is the | |
237 | name of the function, `Message` is an error message describing the problem, | |
238 | `Val` is the value of the argument that is at a pole, and __Policy is the | |
239 | current policy in use for the function that was called. | |
240 | ||
241 | The default behaviour of this function is to throw a std::domain_error exception. | |
242 | But __error_policy can be used to change this, for example to `ignore_error` | |
243 | and return NaN. | |
244 | ||
245 | Note that in order to support information-rich error messages when throwing | |
246 | exceptions, `Message` must contain | |
247 | a __format recognised format specifier: the argument `val` is inserted into | |
248 | the error message according to the specifier used. | |
249 | ||
250 | For example if `Message` contains a "%1%" then it is replaced by the value of | |
251 | `val` to the full precision of T, where as "%.3g" would contain the value of | |
252 | `val` to 3 digits. See the __format documentation for more details. | |
253 | ||
254 | [heading:overflow_error Numeric Overflow] | |
255 | ||
256 | When the result of a special function is too large to fit in the argument | |
257 | floating-point type, then the function returns the result of: | |
258 | ||
259 | boost::math::policies::raise_overflow_error<T>(FunctionName, Message, __Policy); | |
260 | ||
261 | Where | |
262 | `T` is the floating-point type passed to the function, `FunctionName` is the | |
263 | name of the function, `Message` is an error message describing the problem, | |
264 | and __Policy is the current policy | |
265 | in use for the function that was called. | |
266 | ||
267 | The default policy for this function is that `std::overflow_error` | |
268 | C++ exception is thrown. But if, for example, an `ignore_error` policy | |
269 | is used, then returns `std::numeric_limits<T>::infinity()`. | |
270 | In this situation if the type `T` doesn't support infinities, | |
271 | the maximum value for the type is returned. | |
272 | ||
273 | [heading:underflow_error Numeric Underflow] | |
274 | ||
275 | If the result of a special function is known to be non-zero, but the | |
276 | calculated result underflows to zero, then the function returns the result of: | |
277 | ||
278 | boost::math::policies::raise_underflow_error<T>(FunctionName, Message, __Policy); | |
279 | ||
280 | Where | |
281 | `T` is the floating point type passed to the function, `FunctionName` is the | |
282 | name of the function, `Message` is an error message describing the problem, | |
283 | and __Policy is the current policy | |
284 | in use for the called function. | |
285 | ||
286 | The default version of this function returns zero. | |
287 | But with another policy, like `throw_on_error`, | |
288 | throws an `std::underflow_error` C++ exception. | |
289 | ||
290 | [heading:denorm_error Denormalisation Errors] | |
291 | ||
292 | If the result of a special function is a denormalised value /z/ then the function | |
293 | returns the result of: | |
294 | ||
295 | boost::math::policies::raise_denorm_error<T>(z, FunctionName, Message, __Policy); | |
296 | ||
297 | Where | |
298 | `T` is the floating point type passed to the function, `FunctionName` is the | |
299 | name of the function, `Message` is an error message describing the problem, | |
300 | and __Policy is the current policy | |
301 | in use for the called function. | |
302 | ||
303 | The default version of this function returns /z/. | |
304 | But with another policy, like `throw_on_error` | |
305 | throws an `std::underflow_error` C++ exception. | |
306 | ||
307 | [heading:evaluation_error Evaluation Errors] | |
308 | ||
309 | When a special function calculates a result that is known to be erroneous, | |
310 | or where the result is incalculable then it calls: | |
311 | ||
312 | boost::math::policies::raise_evaluation_error<T>(FunctionName, Message, Val, __Policy); | |
313 | ||
314 | Where | |
315 | `T` is the floating point type passed to the function, `FunctionName` is the | |
316 | name of the function, `Message` is an error message describing the problem, | |
317 | `Val` is the erroneous value, | |
318 | and __Policy is the current policy | |
319 | in use for the called function. | |
320 | ||
321 | The default behaviour of this function is to throw a `boost::math::evaluation_error`. | |
322 | ||
323 | Note that in order to support information rich error messages when throwing | |
324 | exceptions, `Message` must contain | |
325 | a __format recognised format specifier: the argument `val` is inserted into | |
326 | the error message according to the specifier used. | |
327 | ||
328 | For example if `Message` contains a "%1%" then it is replaced by the value of | |
329 | `val` to the full precision of T, where as "%.3g" would contain the value of | |
330 | `val` to 3 digits. See the __format documentation for more details. | |
331 | ||
332 | [heading:indeterminate_result_error Indeterminate Result Errors] | |
333 | ||
334 | When the result of a special function is indeterminate for the value that was | |
335 | passed to it, then the function returns the result of: | |
336 | ||
337 | boost::math::policies::raise_overflow_error<T>(FunctionName, Message, Val, Default, __Policy); | |
338 | ||
339 | Where | |
340 | `T` is the floating-point type passed to the function, `FunctionName` is the | |
341 | name of the function, `Message` is an error message describing the problem, | |
342 | Val is the value for which the result is indeterminate, Default is an | |
343 | alternative default result that must be returned for `ignore_error` and | |
344 | `errno_on_erro` policies, and __Policy is the current policy in use for the | |
345 | function that was called. | |
346 | ||
347 | The default policy for this function is `ignore_error`: note that this error | |
348 | type is reserved for situations where the result is mathematically | |
349 | undefined or indeterminate, but there is none the less a convention for what | |
350 | the result should be: for example the C99 standard specifies that the result | |
351 | of 0[super 0] is 1, even though the result is actually mathematically indeterminate. | |
352 | ||
353 | [heading:rounding_error Rounding Errors] | |
354 | ||
355 | When one of the rounding functions __round, __trunc or __modf is | |
356 | called with an argument that has no integer representation, or | |
357 | is too large to be represented in the result type then the | |
358 | value returned is the result of a call to: | |
359 | ||
360 | boost::math::policies::raise_rounding_error<T>(FunctionName, Message, Val, __Policy); | |
361 | ||
362 | Where | |
363 | `T` is the floating point type passed to the function, `FunctionName` is the | |
364 | name of the function, `Message` is an error message describing the problem, | |
365 | `Val` is the erroneous argument, | |
366 | and __Policy is the current policy in use for the called function. | |
367 | ||
368 | The default behaviour of this function is to throw a `boost::math::rounding_error`. | |
369 | ||
370 | Note that in order to support information rich error messages when throwing | |
371 | exceptions, `Message` must contain | |
372 | a __format recognised format specifier: the argument `val` is inserted into | |
373 | the error message according to the specifier used. | |
374 | ||
375 | For example if `Message` contains a "%1%" then it is replaced by the value of | |
376 | `val` to the full precision of T, where as "%.3g" would contain the value of | |
377 | `val` to 3 digits. See the __format documentation for more details. | |
378 | ||
379 | [heading:checked_narrowing_cast Errors from typecasts] | |
380 | ||
381 | Many special functions evaluate their results at a higher precision | |
382 | than their arguments in order to ensure full machine precision in | |
383 | the result: for example, a function passed a float argument may evaluate | |
384 | its result using double precision internally. Many of the errors listed | |
385 | above may therefore occur not during evaluation, but when converting | |
386 | the result to the narrower result type. The function: | |
387 | ||
388 | template <class T, class __Policy, class U> | |
389 | T checked_narrowing_cast(U const& val, const char* function); | |
390 | ||
391 | Is used to perform these conversions, and will call the error handlers | |
392 | listed above on [link math_toolkit.error_handling.overflow_error overflow], | |
393 | [link math_toolkit.error_handling.underflow_error underflow] or [link math_toolkit.error_handling.denorm_error denormalisation]. | |
394 | ||
395 | [endsect][/section:error_handling Error Handling] | |
396 | ||
397 | [/ | |
398 | Copyright 2006 - 2012 John Maddock and Paul A. Bristow. | |
399 | Distributed under the Boost Software License, Version 1.0. | |
400 | (See accompanying file LICENSE_1_0.txt or copy at | |
401 | http://www.boost.org/LICENSE_1_0.txt). | |
402 | ] | |
403 |