| [section:error_handling Error Handling] |
| |
| [def __format [@../../../../format/index.html Boost.Format]] |
| |
| [heading Quick Reference] |
| |
| Handling of errors by this library is split into two orthogonal parts: |
| |
| * What kind of error has been raised? |
| * What should be done when the error is raised? |
| |
| The kinds of errors that can be raised are: |
| |
| [variablelist |
| [[Domain Error][Occurs when one or more arguments to a function |
| are out of range.]] |
| [[Pole Error][Occurs when the particular arguments cause the function to be |
| evaluated at a pole with no well defined residual value. For example if |
| __tgamma is evaluated at exactly -2, the function approaches different limiting |
| values depending upon whether you approach from just above or just below |
| -2. Hence the function has no well defined value at this point and a |
| Pole Error will be raised.]] |
| [[Overflow Error][Occurs when the result is either infinite, or too large |
| to represent in the numeric type being returned by the function.]] |
| [[Underflow Error][Occurs when the result is not zero, but is too small |
| to be represented by any other value in the type being returned by |
| the function.]] |
| [[Denormalisation Error][Occurs when the returned result would be a denormalised value.]] |
| [[Rounding Error][Occurs when the argument to one of the rounding functions __trunc, |
| __round and __modf can not be represented as an integer type, is |
| outside the range of the result type.]] |
| [[Evaluation Error][Occurs if no method of evaluation is known, |
| or when an internal error occurred that prevented the |
| result from being evaluated: this should never occur, but if it does, then |
| it's likely to be due to an iterative method not converging fast enough.]] |
| [[Indeterminate Result Error][Occurs when the result of a function is not |
| defined for the values that were passed to it.]] |
| ] |
| |
| The action undertaken by each error condition is determined by the current |
| __Policy in effect. This can be changed program-wide by setting some |
| configuration macros, or at namespace scope, or at the call site (by |
| specifying a specific policy in the function call). |
| |
| The available actions are: |
| |
| [variablelist |
| [[throw_on_error][Throws the exception most appropriate to the error condition.]] |
| [[errno_on_error][Sets ::errno to an appropriate value, and then returns the most |
| appropriate result]] |
| [[ignore_error][Ignores the error and simply the returns the most appropriate result.]] |
| [[user_error][Calls a |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol user-supplied error handler].]] |
| ] |
| |
| The following tables show all the permutations of errors and actions, |
| with the *default action for each error shown in bold*: |
| |
| [table Possible Actions for Domain Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][[*Throws `std::domain_error`]]] |
| [[errno_on_error][Sets `::errno` to `EDOM` and returns `std::numeric_limits<T>::quiet_NaN()`]] |
| [[ignore_error][Returns `std::numeric_limits<T>::quiet_NaN()`]] |
| [[user_error][Returns the result of `boost::math::policies::user_domain_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Pole Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error] [[*Throws `std::domain_error`]]] |
| [[errno_on_error][Sets `::errno` to `EDOM` and returns `std::numeric_limits<T>::quiet_NaN()`]] |
| [[ignore_error][Returns `std::numeric_limits<T>::quiet_NaN()`]] |
| [[user_error][Returns the result of `boost::math::policies::user_pole_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Overflow Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][[*Throws `std::overflow_error`]]] |
| [[errno_on_error][Sets `::errno` to `ERANGE` and returns `std::numeric_limits<T>::infinity()`]] |
| [[ignore_error][Returns `std::numeric_limits<T>::infinity()`]] |
| [[user_error][Returns the result of `boost::math::policies::user_overflow_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Underflow Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][Throws `std::underflow_error`]] |
| [[errno_on_error][Sets `::errno` to `ERANGE` and returns 0.]] |
| [[ignore_error][[*Returns 0]]] |
| [[user_error][Returns the result of `boost::math::policies::user_underflow_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Denorm Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][Throws `std::underflow_error`]] |
| [[errno_on_error][Sets `::errno` to `ERANGE` and returns the denormalised value.]] |
| [[ignore_error][[*Returns the denormalised value.]]] |
| [[user_error][Returns the result of `boost::math::policies::user_denorm_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Rounding Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][Throws `boost::math::rounding_error`]] |
| [[errno_on_error][Sets `::errno` to `ERANGE` and returns the largest representable value of the target integer type |
| (or the most negative value if the argument to the function was less than zero).]] |
| [[ignore_error][[*Returns the largest representable value of the target integer type |
| (or the most negative value if the argument to the function was less than zero).]]] |
| [[user_error][Returns the result of `boost::math::policies::user_rounding_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Internal Evaluation Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][[*Throws `boost::math::evaluation_error`]]] |
| [[errno_on_error][Sets `::errno` to `EDOM` and returns the closest approximation found.]] |
| [[ignore_error][Returns the closest approximation found.]] |
| [[user_error][Returns the result of `boost::math::policies::user_evaluation_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| [table Possible Actions for Indeterminate Result Errors |
| [[Action] [Behaviour]] |
| [[throw_on_error][Throws `std::domain_error`]] |
| [[errno_on_error][Sets `::errno` to `EDOM` and returns the same value as `ignore_error`.]] |
| [[ignore_error][[*Returns a default result that depends on the function where the error occurred.]]] |
| [[user_error][Returns the result of `boost::math::policies::user_indeterminate_result_error`: |
| [link math_toolkit.policy.pol_tutorial.user_def_err_pol |
| this function must be defined by the user].]] |
| ] |
| |
| All these error conditions are in namespace boost::math::policies, |
| made available, for example, a by namespace declaration |
| using `namespace boost::math::policies;` or individual using declarations |
| `using boost::math::policies::overflow_error;`. |
| |
| [heading Rationale] |
| |
| The flexibility of the current implementation should be reasonably obvious: the |
| default behaviours were chosen based on feedback during the formal review of |
| this library. It was felt that: |
| |
| * Genuine errors should be flagged with exceptions |
| rather than following C-compatible behaviour and setting `::errno`. |
| * Numeric underflow and denormalised results were not considered to be |
| fatal errors in most cases, so it was felt that these should be ignored. |
| |
| [heading Finding More Information] |
| |
| There are some pre-processor macro defines that can be used to |
| [link math_toolkit.policy.pol_ref.policy_defaults |
| change the policy defaults]. See also the [link math_toolkit.policy |
| policy section]. |
| |
| An example is at the Policy tutorial in |
| [link math_toolkit.policy.pol_tutorial.changing_policy_defaults |
| Changing the Policy Defaults]. |
| |
| Full source code of this typical example of passing a 'bad' argument |
| (negative degrees of freedom) to Student's t distribution |
| is [link math_toolkit.dist.stat_tut.weg.error_eg in the error handling example]. |
| |
| The various kind of errors are described in more detail below. |
| |
| [heading [#domain_error]Domain Errors] |
| |
| When a special function is passed an argument that is outside the range |
| of values for which that function is defined, then the function returns |
| the result of: |
| |
| boost::math::policies::raise_domain_error<T>(FunctionName, Message, Val, __Policy); |
| |
| Where |
| `T` is the floating-point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| Val is the value that was out of range, and __Policy is the current policy |
| in use for the function that was called. |
| |
| The default policy behaviour of this function is to throw a |
| std::domain_error C++ exception. But if the __Policy is to ignore |
| the error, or set global `::errno`, then a NaN will be returned. |
| |
| This behaviour is chosen to assist compatibility with the behaviour of |
| ['ISO/IEC 9899:1999 Programming languages - C] |
| and with the |
| [@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]: |
| |
| [:['"Each of the functions declared above shall return a NaN (Not a Number) |
| if any argument value is a NaN, but it shall not report a domain error. |
| Otherwise, each of the functions declared above shall report a domain error |
| for just those argument values for which:]] |
| |
| [:['"the function description's Returns clause explicitly specifies a domain, and those arguments fall outside the specified domain; or] |
| |
| ['"the corresponding mathematical function value has a non-zero imaginary component; or] |
| |
| ['"the corresponding mathematical function is not mathematically defined.]] |
| |
| [:['"Note 2: A mathematical function is mathematically defined |
| for a given set of argument values if it is explicitly defined |
| for that set of argument values or |
| if its limiting value exists and does not depend on the direction of approach."]] |
| |
| Note that in order to support information-rich error messages when throwing |
| exceptions, `Message` must contain |
| a __format recognised format specifier: the argument `Val` is inserted into |
| the error message according to the specifier used. |
| |
| For example if `Message` contains a "%1%" then it is replaced by the value of |
| `Val` to the full precision of T, where as "%.3g" would contain the value of |
| `Val` to 3 digits. See the __format documentation for more details. |
| |
| [heading [#pole_error]Evaluation at a pole] |
| |
| When a special function is passed an argument that is at a pole |
| without a well defined residual value, then the function returns |
| the result of: |
| |
| boost::math::policies::raise_pole_error<T>(FunctionName, Message, Val, __Policy); |
| |
| Where |
| `T` is the floating point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| `Val` is the value of the argument that is at a pole, and __Policy is the |
| current policy in use for the function that was called. |
| |
| The default behaviour of this function is to throw a std::domain_error exception. |
| But __error_policy can be used to change this, for example to `ignore_error` |
| and return NaN. |
| |
| Note that in order to support information-rich error messages when throwing |
| exceptions, `Message` must contain |
| a __format recognised format specifier: the argument `val` is inserted into |
| the error message according to the specifier used. |
| |
| For example if `Message` contains a "%1%" then it is replaced by the value of |
| `val` to the full precision of T, where as "%.3g" would contain the value of |
| `val` to 3 digits. See the __format documentation for more details. |
| |
| [heading [#overflow_error]Numeric Overflow] |
| |
| When the result of a special function is too large to fit in the argument |
| floating-point type, then the function returns the result of: |
| |
| boost::math::policies::raise_overflow_error<T>(FunctionName, Message, __Policy); |
| |
| Where |
| `T` is the floating-point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| and __Policy is the current policy |
| in use for the function that was called. |
| |
| The default policy for this function is that `std::overflow_error` |
| C++ exception is thrown. But if, for example, an `ignore_error` policy |
| is used, then returns `std::numeric_limits<T>::infinity()`. |
| In this situation if the type `T` doesn't support infinities, |
| the maximum value for the type is returned. |
| |
| [heading [#underflow_error]Numeric Underflow] |
| |
| If the result of a special function is known to be non-zero, but the |
| calculated result underflows to zero, then the function returns the result of: |
| |
| boost::math::policies::raise_underflow_error<T>(FunctionName, Message, __Policy); |
| |
| Where |
| `T` is the floating point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| and __Policy is the current policy |
| in use for the called function. |
| |
| The default version of this function returns zero. |
| But with another policy, like `throw_on_error`, |
| throws an `std::underflow_error` C++ exception. |
| |
| [heading [#denorm_error]Denormalisation Errors] |
| |
| If the result of a special function is a denormalised value /z/ then the function |
| returns the result of: |
| |
| boost::math::policies::raise_denorm_error<T>(z, FunctionName, Message, __Policy); |
| |
| Where |
| `T` is the floating point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| and __Policy is the current policy |
| in use for the called function. |
| |
| The default version of this function returns /z/. |
| But with another policy, like `throw_on_error` |
| throws an `std::underflow_error` C++ exception. |
| |
| [heading [#evaluation_error]Evaluation Errors] |
| |
| When a special function calculates a result that is known to be erroneous, |
| or where the result is incalculable then it calls: |
| |
| boost::math::policies::raise_evaluation_error<T>(FunctionName, Message, Val, __Policy); |
| |
| Where |
| `T` is the floating point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| `Val` is the erroneous value, |
| and __Policy is the current policy |
| in use for the called function. |
| |
| The default behaviour of this function is to throw a `boost::math::evaluation_error`. |
| |
| Note that in order to support information rich error messages when throwing |
| exceptions, `Message` must contain |
| a __format recognised format specifier: the argument `val` is inserted into |
| the error message according to the specifier used. |
| |
| For example if `Message` contains a "%1%" then it is replaced by the value of |
| `val` to the full precision of T, where as "%.3g" would contain the value of |
| `val` to 3 digits. See the __format documentation for more details. |
| |
| [heading [#indeterminate_result_error]Indeterminate Result Errors] |
| |
| When the result of a special function is indeterminate for the value that was |
| passed to it, then the function returns the result of: |
| |
| boost::math::policies::raise_overflow_error<T>(FunctionName, Message, Val, Default, __Policy); |
| |
| Where |
| `T` is the floating-point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| Val is the value for which the result is indeterminate, Default is an |
| alternative default result that must be returned for `ignore_error` and |
| `errno_on_erro` policies, and __Policy is the current policy in use for the |
| function that was called. |
| |
| The default policy for this function is `ignore_error`: note that this error |
| type is reserved for situations where the result is mathematically |
| undefined or indeterminate, but there is none the less a convention for what |
| the result should be: for example the C99 standard specifies that the result |
| of 0[super 0] is 1, even though the result is actually mathematically indeterminate. |
| |
| [heading [#rounding_error]Rounding Errors] |
| |
| When one of the rounding functions __round, __trunc or __modf is |
| called with an argument that has no integer representation, or |
| is too large to be represented in the result type then the |
| value returned is the result of a call to: |
| |
| boost::math::policies::raise_rounding_error<T>(FunctionName, Message, Val, __Policy); |
| |
| Where |
| `T` is the floating point type passed to the function, `FunctionName` is the |
| name of the function, `Message` is an error message describing the problem, |
| `Val` is the erroneous argument, |
| and __Policy is the current policy in use for the called function. |
| |
| The default behaviour of this function is to throw a `boost::math::rounding_error`. |
| |
| Note that in order to support information rich error messages when throwing |
| exceptions, `Message` must contain |
| a __format recognised format specifier: the argument `val` is inserted into |
| the error message according to the specifier used. |
| |
| For example if `Message` contains a "%1%" then it is replaced by the value of |
| `val` to the full precision of T, where as "%.3g" would contain the value of |
| `val` to 3 digits. See the __format documentation for more details. |
| |
| [heading [#checked_narrowing_cast]Errors from typecasts] |
| |
| Many special functions evaluate their results at a higher precision |
| than their arguments in order to ensure full machine precision in |
| the result: for example, a function passed a float argument may evaluate |
| its result using double precision internally. Many of the errors listed |
| above may therefore occur not during evaluation, but when converting |
| the result to the narrower result type. The function: |
| |
| template <class T, class __Policy, class U> |
| T checked_narrowing_cast(U const& val, const char* function); |
| |
| Is used to perform these conversions, and will call the error handlers |
| listed above on [link overflow_error overflow], |
| [link underflow_error underflow] or [link denorm_error denormalisation]. |
| |
| [endsect][/section:error_handling Error Handling] |
| |
| [/ |
| Copyright 2006 - 2010 John Maddock and Paul A. Bristow. |
| Distributed under the Boost Software License, Version 1.0. |
| (See accompanying file LICENSE_1_0.txt or copy at |
| http://www.boost.org/LICENSE_1_0.txt). |
| ] |
| |