matherr(3) Library Functions Manual matherr(3)

ИМЯ

matherr - библиотека SVID для обработки математических исключений

Math library (libm, -lm)

СИНТАКСИС

#include <math.h>
[[deprecated]] int matherr(struct exception *exc);
[[deprecated]] extern _LIB_VERSION_TYPE _LIB_VERSION;

ОПИСАНИЕ

Замечание: механизм, описанный на этой странице, больше не поддерживается glibc. До glibc 2.27 он был помечен как устаревший. Начиная с glibc 2.27, механизм был полностью удалён. В новых приложениях нужно использовать методы, описанные в math_error(7) и fenv(3). На этой странице описан механизм matherr() с целью сопровождения и переноса старых приложений.

В System V Interface Definition (SVID) определено какие математические функции должны вызывать функцию matherr(), если обнаруживается математическое исключение. Эта функция вызывает до возврата из самой математической функции; после возврата из matherr() система возвращается в математическую функцию, которая, в свою очередь, возвращает управление вызывающему.

Чтобы задействовать matherr(), программист должен определить макрос тестирования свойств _SVID_SOURCE (до включения каких-либо заголовочных файлов) и присвоить значение _SVID_ внешней переменной _LIB_VERSION.

Система предоставляет matherr() как версию по умолчанию. Эта версия ничего не делает возвращает ноль (назначение этого смотрите далее). Версия по умолчанию matherr() может быть перезаписана версией программиста, которая будет вызываться при возникновении исключений. Функция вызывается с одним аргументом, указателем на структуру exception, определённую следующим образом:


struct exception {
    int    type;      /* тип исключения */
    char  *name;      /* имя функции, вызвавшей исключение */
    double arg1;      /* 1-й аргумент функции */
    double arg2;      /* 2-й аргумент функции */
    double retval;    /* значение, возвращаемое функцией */
}

В поле type может быть одно из следующих значений:

Произошла ошибка области (аргумент функции вне диапазона, для которого определена функция). Возвращаемое значение зависит от функции; errno присваивается EDOM.
Произошла ошибка особой точки (результат функции равен бесконечности). Возвращаемое значение, в большинстве случаев, равно HUGE (самое большое число с плавающей запятой одинарной точности) с соответствующим знаком. В большинстве случаев, errno присваивается EDOM.
Возникло переполнение. В большинстве случаев, возвращается значение HUGE и errno присваивается ERANGE.
Произошла потеря значимости. Возвращается 0.0 и errno присваивается ERANGE.
Полная потеря значимости. Возвращается 0.0 и errno присваивается ERANGE.
Частичная потеря значимости. Это значение не используется в glibc (и многих других системах).

Поля arg1 и arg2 это значения аргументов, переданных функции (arg2 не определено для функций, у которых только один аргумент).

В поле retval указывается возвращаемое значение, которое математическая функция вернёт вызывающему. Написанная программистом matherr() может изменить этого поле, чтобы вернуть другое значение из математической функции.

Если функция matherr() возвращает ноль, то система изменяет errno как описано выше и может вывести сообщение об ошибке в стандартный поток ошибок (смотрите далее).

Если функция matherr() возвращает ненулевое значение, то система не изменяет errno и не печатает сообщение об ошибке.

Математические функции, которые используют matherr()

В таблице далее перечислены функции и обстоятельства вызова matherr(). В столбце «тип» показано значение, назначаемое exc->type, когда вызывается matherr(). В столбце «результат» содержится возвращаемое значение по умолчанию. назначаемое exc->retval.

В столбцах «сообщение?» и «errno» описано поведение по умолчанию, если matherr() возвращает ноль. Если в «сообщение?» указано «y», то система выводит сообщение об ошибке в стандартный поток ошибок.

В таблице используются следующие обозначения и сокращения:

x first argument to function
y second argument to function
fin finite value for argument
neg negative value for argument
int integral value for argument
o/f result overflowed
u/f result underflowed
|x| absolute value of x
X_TLOSS is a constant defined in <math.h>
функция тип результат Сообщение? errno
acos(|x|>1) DOMAIN HUGE и EDOM
asin(|x|>1) DOMAIN HUGE и EDOM
atan2(0,0) DOMAIN HUGE и EDOM
acosh(x<1) DOMAIN NAN и EDOM
atanh(|x|>1) DOMAIN NAN и EDOM
atanh(|x|==1) SING (x>0.0)? и EDOM
    HUGE_VAL :
    -HUGE_VAL
cosh(fin) o/f OVERFLOW HUGE н ERANGE
sinh(fin) o/f OVERFLOW (x>0.0) ? н ERANGE
    HUGE : -HUGE
sqrt(x<0) DOMAIN 0.0 и EDOM
hypot(fin,fin) o/f OVERFLOW HUGE н ERANGE
exp(fin) o/f OVERFLOW HUGE н ERANGE
exp(fin) u/f UNDERFLOW 0.0 н ERANGE
exp2(fin) o/f OVERFLOW HUGE н ERANGE
exp2(fin) u/f UNDERFLOW 0.0 н ERANGE
exp10(fin) o/f OVERFLOW HUGE н ERANGE
exp10(fin) u/f UNDERFLOW 0.0 н ERANGE
j0(|x|>X_TLOSS) TLOSS 0.0 и ERANGE
j1(|x|>X_TLOSS) TLOSS 0.0 и ERANGE
jn(|x|>X_TLOSS) TLOSS 0.0 и ERANGE
y0(x>X_TLOSS) TLOSS 0.0 и ERANGE
y1(x>X_TLOSS) TLOSS 0.0 и ERANGE
yn(x>X_TLOSS) TLOSS 0.0 и ERANGE
y0(0) DOMAIN -HUGE и EDOM
y0(x<0) DOMAIN -HUGE и EDOM
y1(0) DOMAIN -HUGE и EDOM
y1(x<0) DOMAIN -HUGE и EDOM
yn(n,0) DOMAIN -HUGE и EDOM
yn(x<0) DOMAIN -HUGE и EDOM
lgamma(fin) o/f OVERFLOW HUGE н ERANGE
lgamma(-int) или SING HUGE и EDOM
  lgamma(0)
tgamma(fin) o/f OVERFLOW HUGE_VAL н ERANGE
tgamma(-int) SING NAN и EDOM
tgamma(0) SING copysign( и ERANGE
    HUGE_VAL,x)
log(0) SING -HUGE и EDOM
log(x<0) DOMAIN -HUGE и EDOM
log2(0) SING -HUGE н EDOM
log2(x<0) DOMAIN -HUGE н EDOM
log10(0) SING -HUGE и EDOM
log10(x<0) DOMAIN -HUGE и EDOM
pow(0.0,0.0) DOMAIN 0.0 и EDOM
pow(x,y) o/f OVERFLOW HUGE н ERANGE
pow(x,y) u/f UNDERFLOW 0.0 н ERANGE
pow(NaN,0.0) DOMAIN x н EDOM
0**neg DOMAIN 0.0 и EDOM
neg**non-int DOMAIN 0.0 и EDOM
scalb() o/f OVERFLOW (x>0.0) ? н ERANGE
    HUGE_VAL :
    -HUGE_VAL
scalb() u/f UNDERFLOW copysign( н ERANGE
      0.0,x)
fmod(x,0) DOMAIN x и EDOM
remainder(x,0) DOMAIN NAN и EDOM

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes(7).

Интерфейс Атрибут Значение
matherr() Безвредность в нитях MT-Safe

ПРИМЕРЫ

В примере программы показано использование matherr() при вызове log(3). Программа имеет три аргумента командной строки. Первый аргумент — число с плавающей запятой, передаваемое в log(3). Если указан необязательный второй аргумент, то _LIB_VERSION присваивается значение _SVID_ для того, чтобы вызывалась matherr(), и указанное в командной строке целое число используется как возвращаемое значение matherr(). Если указан необязательный третий аргумент, то им определяется альтернативное возвращаемое значение, которое matherr() должна вернуть как результат математической функции.

Пример запуска, где в log(3) передаётся аргумент 0.0 и не используется matherr():


$ ./a.out 0.0
errno: Числовой результат вне представимого диапазона
x=-inf

В следующем примере вызывается функция matherr() и возвращает 0:


$ ./a.out 0.0 0
исключение matherr SING в функции log()
        арг:   0.000000, 0.000000
        возвр.знач.: -340282346638528859811704183484516925440.000000
log: SING error
errno: Числовой аргумент вне области функции
x=-340282346638528859811704183484516925440.000000

Сообщение «log: SING error» выдаётся библиотекой Си.

В следующем примере вызывается функция matherr() и возвращается не нулевое значение:


$ ./a.out 0.0 1
исключение matherr SING в функции log()
        арг:   0.000000, 0.000000
        возвр.знач.: -340282346638528859811704183484516925440.000000
x=-340282346638528859811704183484516925440.000000

В этом случае библиотека Си не печатает сообщение, и значение errno не изменяется.

В следующем примере вызывается функция matherr(), изменяется возвращаемое значение математической функции и возвращается ненулевое значение:


$ ./a.out 0.0 1 12345.0
исключение matherr SING в функции log()
        арг:   0.000000, 0.000000
        возвр.знач.: -340282346638528859811704183484516925440.000000
x=12345.000000

Исходный код программы

#define _SVID_SOURCE
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
static int matherr_ret = 0;     /* Value that matherr()
                                   should return */
static int change_retval = 0;   /* Should matherr() change
                                   function's return value? */
static double new_retval;       /* New function return value */
int
matherr(struct exception *exc)
{
    fprintf(stderr, "matherr %s exception in %s() function\n",
            (exc->type == DOMAIN) ?    "DOMAIN" :
            (exc->type == OVERFLOW) ?  "OVERFLOW" :
            (exc->type == UNDERFLOW) ? "UNDERFLOW" :
            (exc->type == SING) ?      "SING" :
            (exc->type == TLOSS) ?     "TLOSS" :
            (exc->type == PLOSS) ?     "PLOSS" : "???",
            exc->name);
    fprintf(stderr, "        args:   %f, %f\n",
            exc->arg1, exc->arg2);
    fprintf(stderr, "        retval: %f\n", exc->retval);
    if (change_retval)
        exc->retval = new_retval;
    return matherr_ret;
}
int
main(int argc, char *argv[])
{
    double x;
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <argval>"
                " [<matherr-ret> [<new-func-retval>]]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    if (argc > 2) {
        _LIB_VERSION = _SVID_;
        matherr_ret = atoi(argv[2]);
    }
    if (argc > 3) {
        change_retval = 1;
        new_retval = atof(argv[3]);
    }
    x = log(atof(argv[1]));
    if (errno != 0)
        perror("errno");
    printf("x=%f\n", x);
    exit(EXIT_SUCCESS);
}

СМОТРИТЕ ТАКЖЕ

fenv(3), math_error(7), standards(7)

ПЕРЕВОД

Русский перевод этой страницы руководства разработал aereiae <aereiae@gmail.com>, Alexey <a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Малянов Евгений Викторович <maljanow@outlook.com>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.

2 мая 2024 г. Linux man-pages 6.8