1[section:error_handling Error Handling] 2 3[def __format [@../../../format/index.html Boost.Format]] 4 5[heading Quick Reference] 6 7Handling 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[role red If you do not try to catch the exception, you will not see the message!]] 14 15The 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 43The action undertaken by each error condition is determined by the current 44__Policy in effect. This can be changed program-wide by setting some 45configuration macros, or at namespace scope, or at the call site (by 46specifying a specific policy in the function call). 47 48The 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 53appropriate 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 59The following tables show all the permutations of errors and actions, 60with 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 144All these error conditions are in namespace boost::math::policies, 145made available, for example, a by namespace declaration 146using `namespace boost::math::policies;` or individual using declarations 147`using boost::math::policies::overflow_error;`. 148 149[heading Rationale] 150 151The flexibility of the current implementation should be reasonably obvious: the 152default behaviours were chosen based on feedback during the formal review of 153this library. It was felt that: 154 155* Genuine errors should be flagged with exceptions 156rather than following C-compatible behaviour and setting `::errno`. 157* Numeric underflow and denormalised results were not considered to be 158fatal errors in most cases, so it was felt that these should be ignored. 159* If there is more than one error, 160only the first detected will be reported in the throw message. 161 162[heading Finding More Information] 163 164There are some pre-processor macro defines that can be used to 165[link math_toolkit.pol_ref.policy_defaults 166change the policy defaults]. See also the [link policy 167policy section]. 168 169An example is at the Policy tutorial in 170[link math_toolkit.pol_tutorial.changing_policy_defaults 171Changing the Policy Defaults]. 172 173Full source code of this typical example of passing a 'bad' argument 174(negative degrees of freedom) to Student's t distribution 175is [link math_toolkit.stat_tut.weg.error_eg in the error handling example]. 176 177The various kind of errors are described in more detail below. 178 179[heading:domain_error Domain Errors] 180 181When a special function is passed an argument that is outside the range 182of values for which that function is defined, then the function returns 183the result of: 184 185 boost::math::policies::raise_domain_error<T>(FunctionName, Message, Val, __Policy); 186 187Where 188`T` is the floating-point type passed to the function, `FunctionName` is the 189name of the function, `Message` is an error message describing the problem, 190Val is the value that was out of range, and __Policy is the current policy 191in use for the function that was called. 192 193The default policy behaviour of this function is to throw a 194std::domain_error C++ exception. But if the __Policy is to ignore 195the error, or set global `::errno`, then a NaN will be returned. 196 197This behaviour is chosen to assist compatibility with the behaviour of 198['ISO/IEC 9899:1999 Programming languages - C] 199and 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) 203if any argument value is a NaN, but it shall not report a domain error. 204Otherwise, each of the functions declared above shall report a domain error 205for just those argument values for which:[br] 206the function description's Returns clause explicitly specifies a domain, and those arguments fall outside the specified domain; or [br] 207the corresponding mathematical function value has a non-zero imaginary component; or [br] 208the corresponding mathematical function is not mathematically defined. [br] 209Note 2: A mathematical function is mathematically defined 210for a given set of argument values if it is explicitly defined 211for that set of argument values or 212if its limiting value exists and does not depend on the direction of approach.\"]] 213 214Note that in order to support information-rich error messages when throwing 215exceptions, `Message` must contain 216a __format recognised format specifier: the argument `Val` is inserted into 217the error message according to the specifier used. 218 219For example if `Message` contains a "%1%" then it is replaced by the value of 220`Val` to the full precision of T, where as "%.3g" would contain the value of 221`Val` to 3 digits. See the __format documentation for more details. 222 223[heading:pole_error Evaluation at a pole] 224 225When a special function is passed an argument that is at a pole 226without a well defined residual value, then the function returns 227the result of: 228 229 boost::math::policies::raise_pole_error<T>(FunctionName, Message, Val, __Policy); 230 231Where 232`T` is the floating point type passed to the function, `FunctionName` is the 233name of the function, `Message` is an error message describing the problem, 234`Val` is the value of the argument that is at a pole, and __Policy is the 235current policy in use for the function that was called. 236 237The default behaviour of this function is to throw a std::domain_error exception. 238But __error_policy can be used to change this, for example to `ignore_error` 239and return NaN. 240 241Note that in order to support information-rich error messages when throwing 242exceptions, `Message` must contain 243a __format recognised format specifier: the argument `val` is inserted into 244the error message according to the specifier used. 245 246For example if `Message` contains a "%1%" then it is replaced by the value of 247`val` to the full precision of T, where as "%.3g" would contain the value of 248`val` to 3 digits. See the __format documentation for more details. 249 250[heading:overflow_error Numeric Overflow] 251 252When the result of a special function is too large to fit in the argument 253floating-point type, then the function returns the result of: 254 255 boost::math::policies::raise_overflow_error<T>(FunctionName, Message, __Policy); 256 257Where 258`T` is the floating-point type passed to the function, `FunctionName` is the 259name of the function, `Message` is an error message describing the problem, 260and __Policy is the current policy 261in use for the function that was called. 262 263The default policy for this function is that `std::overflow_error` 264C++ exception is thrown. But if, for example, an `ignore_error` policy 265is used, then returns `std::numeric_limits<T>::infinity()`. 266In this situation if the type `T` doesn't support infinities, 267the maximum value for the type is returned. 268 269[heading:underflow_error Numeric Underflow] 270 271If the result of a special function is known to be non-zero, but the 272calculated result underflows to zero, then the function returns the result of: 273 274 boost::math::policies::raise_underflow_error<T>(FunctionName, Message, __Policy); 275 276Where 277`T` is the floating point type passed to the function, `FunctionName` is the 278name of the function, `Message` is an error message describing the problem, 279and __Policy is the current policy 280in use for the called function. 281 282The default version of this function returns zero. 283But with another policy, like `throw_on_error`, 284throws an `std::underflow_error` C++ exception. 285 286[heading:denorm_error Denormalisation Errors] 287 288If the result of a special function is a denormalised value /z/ then the function 289returns the result of: 290 291 boost::math::policies::raise_denorm_error<T>(z, FunctionName, Message, __Policy); 292 293Where 294`T` is the floating point type passed to the function, `FunctionName` is the 295name of the function, `Message` is an error message describing the problem, 296and __Policy is the current policy 297in use for the called function. 298 299The default version of this function returns /z/. 300But with another policy, like `throw_on_error` 301throws an `std::underflow_error` C++ exception. 302 303[heading:evaluation_error Evaluation Errors] 304 305When a special function calculates a result that is known to be erroneous, 306or where the result is incalculable then it calls: 307 308 boost::math::policies::raise_evaluation_error<T>(FunctionName, Message, Val, __Policy); 309 310Where 311`T` is the floating point type passed to the function, `FunctionName` is the 312name of the function, `Message` is an error message describing the problem, 313`Val` is the erroneous value, 314and __Policy is the current policy 315in use for the called function. 316 317The default behaviour of this function is to throw a `boost::math::evaluation_error`. 318 319Note that in order to support information rich error messages when throwing 320exceptions, `Message` must contain 321a __format recognised format specifier: the argument `val` is inserted into 322the error message according to the specifier used. 323 324For example if `Message` contains a "%1%" then it is replaced by the value of 325`val` to the full precision of T, where as "%.3g" would contain the value of 326`val` to 3 digits. See the __format documentation for more details. 327 328[heading:indeterminate_result_error Indeterminate Result Errors] 329 330When the result of a special function is indeterminate for the value that was 331passed to it, then the function returns the result of: 332 333 boost::math::policies::raise_overflow_error<T>(FunctionName, Message, Val, Default, __Policy); 334 335Where 336`T` is the floating-point type passed to the function, `FunctionName` is the 337name of the function, `Message` is an error message describing the problem, 338Val is the value for which the result is indeterminate, Default is an 339alternative default result that must be returned for `ignore_error` and 340`errno_on_erro` policies, and __Policy is the current policy in use for the 341function that was called. 342 343The default policy for this function is `ignore_error`: note that this error 344type is reserved for situations where the result is mathematically 345undefined or indeterminate, but there is none the less a convention for what 346the result should be: for example the C99 standard specifies that the result 347of 0[super 0] is 1, even though the result is actually mathematically indeterminate. 348 349[heading:rounding_error Rounding Errors] 350 351When one of the rounding functions __round, __trunc or __modf is 352called with an argument that has no integer representation, or 353is too large to be represented in the result type then the 354value returned is the result of a call to: 355 356 boost::math::policies::raise_rounding_error<T>(FunctionName, Message, Val, __Policy); 357 358Where 359`T` is the floating point type passed to the function, `FunctionName` is the 360name of the function, `Message` is an error message describing the problem, 361`Val` is the erroneous argument, 362and __Policy is the current policy in use for the called function. 363 364The default behaviour of this function is to throw a `boost::math::rounding_error`. 365 366Note that in order to support information rich error messages when throwing 367exceptions, `Message` must contain 368a __format recognised format specifier: the argument `val` is inserted into 369the error message according to the specifier used. 370 371For example if `Message` contains a "%1%" then it is replaced by the value of 372`val` to the full precision of T, where as "%.3g" would contain the value of 373`val` to 3 digits. See the __format documentation for more details. 374 375[heading:checked_narrowing_cast Errors from typecasts] 376 377Many special functions evaluate their results at a higher precision 378than their arguments in order to ensure full machine precision in 379the result: for example, a function passed a float argument may evaluate 380its result using double precision internally. Many of the errors listed 381above may therefore occur not during evaluation, but when converting 382the result to the narrower result type. The function: 383 384 template <class T, class __Policy, class U> 385 T checked_narrowing_cast(U const& val, const char* function); 386 387Is used to perform these conversions, and will call the error handlers 388listed above on [link math_toolkit.error_handling.overflow_error overflow], 389[link math_toolkit.error_handling.underflow_error underflow] or [link math_toolkit.error_handling.denorm_error denormalisation]. 390 391[endsect] [/section:error_handling Error Handling] 392 393[/ 394 Copyright 2006 - 2012 John Maddock and Paul A. Bristow. 395 Distributed under the Boost Software License, Version 1.0. 396 (See accompanying file LICENSE_1_0.txt or copy at 397 http://www.boost.org/LICENSE_1_0.txt). 398] 399 400