См.документацию по обработке ошибокдля подробного объяснения механизма обработки ошибок, включая общие «плохие» аргументы для дистрибутивов и функций, и как использоватьПолитика, чтобы контролировать его.
Но, по умолчанию,исключения будут повышены, для ошибок домена, ошибок полюсов, численного переполнения и внутренних ошибок оценки. Чтобы избежать исключений от бросания и вместо этого получить соответствующее значение, обычно NaN (ошибки поля домена или внутренние ошибки) или бесконечность (от переполнения), вам нужно изменить политику.
Следующий пример демонстрирует эффект установки макроса BOOST_MATH_DOMAIN_ERROR_POLICY Когда возникает неверный аргумент. Для целей этого примера мы передаем отрицательный параметр степеней свободы распределению t ученика.
Поскольку мы знаем, что это одна файловая программа, мы можем просто добавить:
#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
в верхней части исходного файла изменить политику по умолчанию на ту, которая просто возвращает NaN, когда происходит ошибка домена. В качестве альтернативы мы можем использовать:
#define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
Чтобы убедиться, что<::errno
>установлен, когда происходит ошибка домена, а также возвращает NaN.
Это безопасно, если программа состоит из одного блока переводаи, мы размещаем определениепередлюбыми #включает. Обратите внимание, что если мы добавим определение после включения, то оно не будет иметь никакого эффекта! Предупреждение, такое как:
warning C4005: 'BOOST_MATH_OVERFLOW_ERROR_POLICY' : macro redefinition
Это является определенным признаком того, что оннебудет иметь желаемый эффект.
Мы начнем нашу выборочную программу с необходимых включений:
#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
#include <boost/math/distributions/students_t.hpp>
using boost::math::students_t;
#include <iostream>
using std::cout;
using std::endl;
#include <stdexcept>
#include <cstddef>
Далее мы определим основной() программы, чтобы назвать распределение студента t с недействительным параметром степеней свободы, программа настроена для обработки либо исключения, либо NaN:
int main()
{
cout << "Example error handling using Student's t function. " << endl;
cout << "BOOST_MATH_DOMAIN_ERROR_POLICY is set to: "
<< BOOST_STRINGIZE(BOOST_MATH_DOMAIN_ERROR_POLICY) << endl;
double degrees_of_freedom = -1;
double t = 10;
try
{
errno = 0;
students_t dist(degrees_of_freedom);
double p = cdf(dist, t);
if((boost::math::isnan)(p))
{
cout << "cdf returned a NaN!" << endl;
if (errno != 0)
{
cout << "errno is set to: " << errno << endl;
}
}
else
cout << "Probability of Student's t is " << p << endl;
}
catch(const std::exception& e)
{
std::cout <<
"\n""Message from thrown exception was:\n " << e.what() << std::endl;
}
return 0;
}
Вот как выглядит вывод программы со сборкой по умолчанию (котораяделает исключения).:
Example error handling using Student's t function.
BOOST_MATH_DOMAIN_ERROR_POLICY is set to: throw_on_error
Message from thrown exception was:
Error in function boost::math::students_t_distribution<double>::students_t_distribution:
Degrees of freedom argument is -1, but must be > 0 !
В качестве альтернативы давайте построим с:
#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
Теперь выход программы:
Example error handling using Student's t function.
BOOST_MATH_DOMAIN_ERROR_POLICY is set to: ignore_error
cdf returned a NaN!
И, наконец, давайте строить с:
#define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
Что дает выход шоу errno:
Example error handling using Student's t function.
BOOST_MATH_DOMAIN_ERROR_POLICY is set to: errno_on_error
cdf returned a NaN!
errno is set to: 33
![[Caution]](/img/caution.png) |
Caution |
Если включен бросок исключений (по умолчанию), но у вас есть, а не, попробуйте & catch block, то программа закончится с непойманным исключением и, вероятно, прервется.
Поэтому для получения пользы от полезных сообщений об ошибках, позволяющихвсе исключения и использование try & catchрекомендуется для большинства приложений.
Однако для простоты это не делается для большинства примеров.
|