Функция Процедура обработки ошибок операций с
плавающей точкой, модифицируемая
пользователем
Синтаксис #include
int matherr(struct exception *e);
Файл, содержащий math.h
прототип
Описание Функция matherr вызывается для обработки ошибок,
генерируемых функциями из библиотеки математичес-
ких функций.
matherr служит в качестве пользовательской ловуш-
ки, (функции определяемой пользователем) которую
вы можете написать сами (смотрите пример).
matherr сожно использовать для отслеживания оши-
бок области определения и выхода за пределы диа-
пазона, происходящих в математических функциях.
Она не отслеживает исключительных ситуаций, воз-
никающих при работе со значениями с плавающей
точкой (например при делении на 0). Для отслежи-
вания таких ошибок смотри функцию signal.
Вы можете модифицировать процедуру matherr специ-
ально для вашего случая (то есть она будет отлав-
ливать определенные типы ошибок); модифицирован-
ная функция matherr должна возвращать 0, если она
не может обработать данную ошибку, и 1, если
ошибка успешно обработана. Если функция matherr
возвращает ненулевое значение, сообщение об ошиб-
ке не печатается, и переменная errno не изменяет-
ся.
Ниже приведена структура exception (определенная
в файле math.h):
struct exception {
int type;
char *Function;
double arg1, arg2, retval;
};
Составные части структуры exception обозначают
следующее:
---------T-------------------------------------------------¬
¦Имя ¦ Что это ¦
+--------+-------------------------------------------------+
¦type ¦ тип произошедшей математической ошибки; тип enum¦
¦ ¦ определен в typedef_mexcep (смотрите определение¦
¦ ¦ после данного списка). ¦
¦Function¦ указатель на символьную строку с нулевым ¦
¦ ¦ окончанием, содержащую имя библиотечной ¦
¦ ¦ математической функции, которая выдала ошибку. ¦
¦arg1, ¦ аргументы (переданные данной функции), которые ¦
¦arg2 ¦ вызвали ошибку; если функции передается только ¦
¦ ¦ один аргумент, он хранится в arg1. ¦
¦retval ¦ стандартное возвращаемое значение для функции ¦
¦ ¦ matherr; вы можете модифицировать это значение. ¦
L--------+--------------------------------------------------
Параметр typedef_mexcep, также определенный в
файле math.h, перечисляет следующие символические
константы, представляющие собой возможные матема-
тические ошибки:
----------------T------------------------------------------¬
¦Символическая ¦ Математическая ошибка ¦
¦константа ¦ ¦
+---------------+------------------------------------------+
¦DOMAIN ¦ аргумент не находится в области ¦
¦ ¦ определения функции (например log(-1)); ¦
¦SING ¦ аргументы дают ошибку в сингулярности ¦
¦ ¦ (например pow(0,-2)); ¦
¦OVERFLOW ¦ аргумент приводит к результату, превыша- ¦
¦ ¦ ющему MAXDOUBLE (например exp(1000)); ¦
¦UNDERFLOW ¦ аргумент приводит к результату, меньшему ¦
¦ ¦ MINDOUBLE (например exp(-1000)); ¦
¦TLOSS ¦ аргументы дают результат с потерей значащ¦
¦ ¦ цифр например sin(10e70)). ¦
L---------------+-------------------------------------------
Символические константы MAXDOUBLE и MINDOUBLE оп-
ределены в файле values.h.
Исходный код для функции matherr, определенной по
умолчанию находится на дистрибутивных дисках с
системой Turbo C++.
Стандарт UNIX функции matherr несовместим со
стандартом ANSI C. Если вам требуется версия фун-
кции matherr для системы UNIX, пользуйтесь прог-
раммой matherr.c, поставляемой на дистрибутивных
дискетах пакета Turbo C.
Возвращаемое значение
По умолчанию функция matherr возвращает 1 если
ошибка UNDERFLOW или TLOSS, иначе 0. Функция
matherr также может модифицировать параметр
e->retval, который посредством функции matherr
передается в вызывающую программу.
Когда функция matherr возвращает 0, (означающий,
что обработать ошибку она не может), функция
_matherr устанавливает переменную errno и печатает
сообщение об ошибке. Когда функция matherr возвра-
щает ненулевое значение, (означающее, что ошибка
успешно обработана), глобальная переменная errno
не устанавливается и сообщение об ошибке не выво-
дится.
Переносимость
matherr доступна на многих компиляторах Си, одна-
ко она не поддерживается стандартом ANSI C.
matherr в стиле системы UNIX (которая печатает
сообшение и завершает выполнение программы) пос-
тавляется вместе с пакетом Turbo C++ в файле
MATHERR.C. matherr может не поддерживаться в
дальнейших версиях Turbo C++.
Пример:
#include
#include
#include
int matherr(struct exception *a);
{
if (a -> type == DOMAIN)
{
if(strcmp(a -> name, "sqrt") == 0)
{
a -> retval = sqrt (-(a -> arg1));
return (1);
}
}
return (0);
}
int main(void)
{
double x,y;
x = -2.0;
y = sqrt(x);
printf("Значение, скорректированное matherr: %lf\n",y);
return 0;
}