「標準とBoostのround - デフォルトの挙動」からの続きです。
Boost.Mathのround()関数は、デフォルトでは値域エラー時にrounding_error例外を投げます。
Boost.Mathでは、例外が投げられることが好ましくない場合は、その挙動をカスタマイズできます。以下は、エラーを無視する場合の指定です。
#include <iostream> #include <boost/math/special_functions/round.hpp> #include <limits> namespace policies = boost::math::policies; typedef policies::policy< policies::rounding_error<policies::ignore_error> > round_policy; int main() { double x = boost::math::round(std::numeric_limits<double>::quiet_NaN(), round_policy()); std::cout << x << std::endl; }
-1.79769e+308
round()関数の第2引数としてエラー時の動作ポリシーを指定することで、round()関数内でエラーが起きた時の挙動をカスタマイズできます。ポリシーの指定には、boost::math::policies名前空間にある、policyメタ関数を使用します。
policyメタ関数には、エラーの種類ごとの挙動を設定します。round()関数では値域エラーしか起こらないので、rounding_errorのみを指定しています。そしてここでは、値域エラー発生時にignore_error、すなわちエラーを無視するよう指定しています。
他のものも見て行きましょう。
エラー時に例外を投げる(throw_on_error)
エラー時に例外を投げるには、boost::math::policies::throw_on_errorを指定します。値域エラーの場合は、boost::math::rounding_errorを指定します。
#include <iostream> #include <boost/math/special_functions/round.hpp> #include <limits> namespace policies = boost::math::policies; typedef policies::policy< policies::rounding_error<policies::throw_on_error> > round_policy; int main() { try { double x = boost::math::round(std::numeric_limits<double>::quiet_NaN(), round_policy()); } catch (boost::math::rounding_error& e) { std::cout << e.what() << std::endl; } }
Error in function boost::math::round<d>(d): Value nan can not be represented in the target integer type.
エラー時にエラー番号を設定する(errno_on_error)
エラー時にerrnoにエラー番号を設定するには、boost::math::policies::errno_on_errorを指定します。値域エラーの場合は、ERANGEが設定されます。
#include <iostream> #include <boost/math/special_functions/round.hpp> #include <limits> namespace policies = boost::math::policies; typedef policies::policy< policies::rounding_error<policies::errno_on_error> > round_policy; int main() { double x = boost::math::round(std::numeric_limits<double>::quiet_NaN(), round_policy()); if (errno == ERANGE) { std::cout << "range error" << std::endl; } }
range error
ユーザー定義のエラー動作をさせる(user_error)
ユーザー定義のエラー動作をさせるには、boost::math::policies::user_errorを指定します。これを指定すると、値域エラーの場合は、先行宣言のみされているboost::math::policies::user_rounding_error()関数が呼ばれるので、その関数を自分で定義します。
#include <iostream> #include <boost/math/special_functions/round.hpp> #include <limits> namespace policies = boost::math::policies; typedef policies::policy< policies::rounding_error<policies::user_error> > round_policy; namespace boost { namespace math { namespace policies { template <class T, class TargetType> T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t) { std::cout << "rounding error" << std::endl; return std::numeric_limits<T>::quiet_NaN(); } }}} int main() { double x = boost::math::round(std::numeric_limits<double>::quiet_NaN(), round_policy()); }
rounding error
round()関数のエラー時挙動カスタマイズについては以上になります。
エラー時ポリシーの設定は、Boost.Mathでの他の関数にも適用できます。詳細は、以下のドキュメントを参照してください:
Error Handling - Boost Math Library