Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

錯誤處理策略(Error Handling Policies)

錯誤處理有兩個正交的方面(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

這些枚舉值具有下面的含義:

throw_on_error

依據錯誤的類型,將會拋出下面的異常之一:

錯誤類型

異常

定義域錯誤(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_on_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

ignore_error

依據錯誤類型,將會返回下列值之一(::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)

依賴於錯誤所發生的函數

user_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

注意參數functionmessage 可能包含"%1%" 格式化分類符號(format specifiers) 來與 Boost.Format庫聯合使用。如果這些字符串將會呈現給程序的最終用戶,那麼"%1%" 格式化分類符號(format specifiers) 將使用類型T的名字在function 字符串中進行替換,如果有一個 %1% 分類符號在message 字符串中,那麼它應當使用val的值進行替換。

指南中有更多關於用戶自定義錯誤處理方法的信息。

產生的錯誤類型(Kinds of Error Raised)

由這個庫報告的錯誤類型有6種,總結在下面的表中:

錯誤類型

策略類

描述

定義域錯誤(Domain Error)

boost::math::policies::domain_error<action>

當有一個或多個參數超出函數的定義域時發生。

缺省為:boost::math::policies::domain_error<throw_on_error>

如果操作設置為throw_on_error 那麼就拋出 std::domain_error 異常

Pole Error

boost::math::policies::pole_error<action>

當有一個或多個參數導致函數在一個pole處計算的時候發生

缺省為:boost::math::policies::pole_error<throw_on_error>

如果操作設置為throw_on_error 那麼就拋出std::domain_error 異常

溢出錯誤 (Overflow Error)

boost::math::policies::overflow_error<action>

當計算的結果太大而無法在所使用的浮點類型中表示的時候發生

缺省為:boost::math::policies::overflow_error<throw_on_error>.

如果操作設置為throw_on_error 那麼就拋出std::overflow_error. 異常

下溢錯誤(Underflow Error)

boost::math::policies::underflow_error<action>

當 計算的結果太小而無法在所使用的浮點類型中表示的時候發生

缺省為:boost::math::policies::underflow_error<ignore_error>

如果操作設置為throw_on_error 那麼就拋出std::underflow_error 異常

Denorm Error

boost::math::policies::denorm_error<action>

當函數的返回值是 denormalised value時發生.

缺省為:boost::math::policies::denorm_error<ignore_error>

如果操作設置為throw_on_error 那麼就拋出std::underflow_error 異常

捨入錯誤(Rounding Error)

boost::math::policies::rounding_error<action>

round, truncmodf 中之一使用一個沒有整數表示的參數調用時,或太大以至於不能在結果類型中表示的時候發生

缺省為:boost::math::policies::rounding_error<throw_on_error>

如果操作設置為throw_on_error 那麼就拋出boost::math::rounding_error 異常

計算錯誤(Evaluation Error)

boost::math::policies::evaluation_error<action>

當函數的返回值是定義良好的(well defined)並且是有限值,但是我們無法計算這個值時發生。通常這會在一個迭代方法不能收斂時發生。當然,理想情況下這種錯誤永遠不應該發生:如果存在這個錯誤,請報告這個bug!

缺省為:boost::math::policies::evaluation_error<throw_on_error>

如果操作設置為throw_on_error 那麼就拋出boost::math::evaluation_error 異常

未定義結果錯誤(Indeterminate Result Error)

boost::math::policies::indeterminate_result_error<action>

當對於傳遞給函數的參數值,函數的結果是未定義的時候發生。

缺省為:boost::math::policies::indeterminate_result_error<ignore_error>

如果操作設置為throw_on_error 那麼就拋出std::domain_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);


PrevUpHomeNext