Благодаря Xuebin Wu из списка рассылки GSL проблема решена:
Привет,
GSL_ERROR сам по себе является макросом, выглядит как
gsl_error (reason, __FILE__, __LINE__, gsl_errno);
return gsl_errno;
функция уже возвращается, прежде чем вы вернете NAN, потому что GSL_ERROR был вызван.Отключение обработчика просто позволяет первой строке ничего не делать.Обработчик ошибок по умолчанию прерывает программу после вывода сообщения об ошибке.
Я не думаю, что это ошибка.Может быть, вы можете написать свой собственный обработчик ошибок, чтобы решить вашу проблему.Например, вы можете использовать «goto», чтобы выпрыгнуть из gsl_integration_qags, или установить некоторую глобальную переменную, чтобы указать, что результат интеграции неверен.
PS: я считаю, что этот макрос - то, что вам нужно,
Макрос: GSL_ERROR_VAL (причина, gsl_errno, значение) Этот макрос такой же, как GSL_ERROR, но возвращает определяемое пользователем значение значения вместо кода ошибки.Его можно использовать для математических функций, которые возвращают значение с плавающей запятой.
В следующем примере показано, как вернуть NaN с математической особенностью, используя макрос GSL_ERROR_VAL,
if (x == 0)
{
GSL_ERROR_VAL("argument lies on singularity",
GSL_ERANGE, GSL_NAN);
}
Итак, я настроилкод в соответствии с
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
double f (double x, void * params) {
// return GSL_NAN;
GSL_ERROR_VAL ("argument lies on singularity", GSL_ERANGE, GSL_NAN);
}
int main (void)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
double result, error;
gsl_function F;
F.function = &f;
gsl_set_error_handler_off();
int status = gsl_integration_qags (&F, 0, 1, 0, 1e-7, 1000,
w, &result, &error);
printf ("status = %d\n", status);
status = GSL_FAILURE;
printf ("status = %d\n", status);
gsl_integration_workspace_free (w);
return 0;
}
и все работает как положено ...