![]() |
Home | Libraries | People | FAQ | More |
錯誤處理有兩個正交的方面(orthogonal aspects):
如何處理錯誤由一個枚舉類型包裝起來:
namespace boost { namespace math { namespace policies { enum error_policy_type { throw_on_error = 0, // 輸出異常. errno_on_error = 1, // 設置 ::errno & 返回 0, NaN, infinity or best guess. ignore_error = 2, // 返回 0, NaN, infinity or best guess. user_error = 3 // 調用一個用戶定義的錯誤處理方法. }; }}} // namespaces
這些枚舉值具有下面的含義:
依據錯誤的類型,將會拋出下面的異常之一:
|
錯誤類型 |
異常 |
|---|---|
|
定義域錯誤(Domain Error ) |
std::domain_error |
|
Pole Error |
std::domain_error |
|
溢出錯誤(Overflow Error) |
std::overflow_error |
|
下溢錯誤(Underflow Error) |
std::underflow_error |
|
Denorm Error |
std::underflow_error |
|
計算錯誤(Evaluation Error) |
boost::math::evaluation_error |
|
未定義結果錯誤(Indeterminate Result Error) |
std::domain_error |
依據錯誤的類型,將會設置全局變量::errno
為以下值之一,如果這種錯誤被忽略的話則返回相同的值。
|
錯誤類型 |
errno 值 |
|---|---|
|
定義域錯誤(Domain Error ) |
EDOM |
|
Pole Error |
EDOM |
|
溢出錯誤(Overflow Error) |
ERANGE |
|
下溢錯誤(Underflow Error) |
ERANGE |
|
Denorm Error |
ERANGE |
|
計算錯誤(Evaluation Error) |
EDOM |
|
未定義結果錯誤(Indeterminate Result Error) |
EDOM |
依據錯誤類型,將會返回下列值之一(::errno值並沒有改變):
|
錯誤類型 |
返回值 |
|---|---|
|
定義域錯誤(Domain Error ) |
std::numeric_limits<T>::quiet_NaN() |
|
Pole Error |
std::numeric_limits<T>::quiet_NaN() |
|
溢出錯誤(Overflow Error) |
std::numeric_limits<T>::infinity() |
|
下溢錯誤(Underflow Error) |
0 |
|
Denorm Error |
The denormalised value. |
|
計算錯誤(Evaluation Error) |
結果的最佳猜測值:可能在錯誤中是有意義的。 |
|
未定義結果錯誤(Indeterminate Result Error) |
依賴於錯誤所發生的函數 |
將會調用 一個用戶定義的錯誤處理方法:這些錯誤處理方法在 boost/math/policies/error_handling.hpp進行了前向聲明(forward declaration),但實際的定義必須由用戶提供:
namespace boost{ namespace math{ namespace policies{ template <class T> T user_domain_error(const char* function, const char* message, const T& val); template <class T> T user_pole_error(const char* function, const char* message, const T& val); template <class T> T user_overflow_error(const char* function, const char* message, const T& val); template <class T> T user_underflow_error(const char* function, const char* message, const T& val); template <class T> T user_denorm_error(const char* function, const char* message, const T& val); template <class T> T user_rounding_error(const char* function, const char* message, const T& val); template <class T> T user_evaluation_error(const char* function, const char* message, const T& val); template <class T> T user_indeterminate_result_error(const char* function, const char* message, const T& val); }}} // namespaces
注意參數function 和 message 可能包含"%1%" 格式化分類符號(format specifiers) 來與 Boost.Format庫聯合使用。如果這些字符串將會呈現給程序的最終用戶,那麼"%1%" 格式化分類符號(format specifiers) 將使用類型T的名字在function 字符串中進行替換,如果有一個 %1% 分類符號在message 字符串中,那麼它應當使用val的值進行替換。
在指南中有更多關於用戶自定義錯誤處理方法的信息。
由這個庫報告的錯誤類型有6種,總結在下面的表中:
|
錯誤類型 |
策略類 |
描述 |
|---|---|---|
|
定義域錯誤(Domain Error) |
boost::math::policies::domain_error<action> |
當有一個或多個參數超出函數的定義域時發生。
缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
|
Pole Error |
boost::math::policies::pole_error<action> |
當有一個或多個參數導致函數在一個pole處計算的時候發生
缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
|
溢出錯誤 (Overflow Error) |
boost::math::policies::overflow_error<action> |
當計算的結果太大而無法在所使用的浮點類型中表示的時候發生 缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
|
下溢錯誤(Underflow Error) |
boost::math::policies::underflow_error<action> |
當 計算的結果太小而無法在所使用的浮點類型中表示的時候發生
缺省為:
如果操作設置為throw_on_error
那麼就拋出 |
|
Denorm Error |
boost::math::policies::denorm_error<action> |
當函數的返回值是 denormalised value時發生.
缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
|
捨入錯誤(Rounding Error) |
boost::math::policies::rounding_error<action> |
當round, trunc 或modf 中之一使用一個沒有整數表示的參數調用時,或太大以至於不能在結果類型中表示的時候發生
缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
|
計算錯誤(Evaluation Error) |
boost::math::policies::evaluation_error<action> |
當函數的返回值是定義良好的(well defined)並且是有限值,但是我們無法計算這個值時發生。通常這會在一個迭代方法不能收斂時發生。當然,理想情況下這種錯誤永遠不應該發生:如果存在這個錯誤,請報告這個bug!
缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
|
未定義結果錯誤(Indeterminate Result Error) |
boost::math::policies::indeterminate_result_error<action> |
當對於傳遞給函數的參數值,函數的結果是未定義的時候發生。
缺省為:
如果操作設置為throw_on_error 那麼就拋出 |
假設我們想要函數tgamma
以一種以兼容( C-compatible)的方式運行,並設置全局變量::errno 而不是拋出一個異常,那我們可以在函數的調用點通過使用下面的方法來達到:
#include <boost/math/special_functions/gamma.hpp> using namespace boost::math::policies; using namespace boost::math; // 定義一個策略: typedef policy< domain_error<errno_on_error>, pole_error<errno_on_error>, overflow_error<errno_on_error>, policies::evaluation_error<errno_on_error> > my_policy; // 調用函數: double t1 = tgamma(some_value, my_policy()); // 另一方面我們可以使用函數 make_policy 並在調用點定義所有的變量 : double t2 = tgamma(some_value, make_policy( domain_error<errno_on_error>(), pole_error<errno_on_error>(), overflow_error<errno_on_error>(), policies::evaluation_error<errno_on_error>() ));
假設我們想要一個統計分佈類型返回無限值,而不是拋出異常,那麼我們可以使用:
#include <boost/math/distributions/normal.hpp> using namespace boost::math::policies; using namespace boost::math; // 定義一個策略: typedef policy< overflow_error<ignore_error> > my_policy; // 定義分佈對像: typedef normal_distribution<double, my_policy> my_norm; // 獲得一個分位點: double q = quantile(my_norm(), 0.05);