math_error(7)

НАИМЕНОВАНИЕ
math_error - определение ошибок при выполнении математических функций

ОБЗОР
#include <math.h>
#include <errno.h>
#include <fenv.h>

ОПИСАНИЕ
При возникновении ошибки большинство библиотечных функций возвращают специальное значение (например, -1 или NULL). Так как математические функции, объявленные в <math.h>, обычно, возвращают число с плавающей запятой, то для выдачи ошибки используются другие способы. Есть два варианта вернуть сообщение об ошибке: старый — изменяя errno; новый — используя механизм исключений плавающей запятой (с помощью feclearexcept(3) и fetestexcept(3) как описано ниже), описанный в fenv(3).

Переносимая программа, которой требуется проверка на ошибки в математических функциях, должна обнулить errno и выполнить вызов

    feclearexcept(FE_ALL_EXCEPT);

перед тем, как вызвать математическую функцию.

По возврату из математической функции, если переменная errno ненулевая, а так же следующий вызов (смотрите fenv(3)) вернул ненулевое значение

    fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW |
                 FE_UNDERFLOW);

то ошибка произошла в математической функции.

Условия возникновения математических ошибок приведены ниже.

  Ошибка области
Ошибка области возникает, когда математической функции передаётся аргумент, чьё значение выходит за границы области, ожидаемой функцией (например, передача отрицательного значения в функцию log(3)). Когда возникает ошибка области, чаще всего, математические функции возвращают NaN (хотя некоторые функции в этом случае возвращают другое значение); errno присваивается EDOM возникает исключение плавающей запятой «invalid» (FE_INVALID).

  Ошибка особой точки
Ошибка особой точки возникает, когда результат математической функции должен быть равен бесконечности (например, логарифм 0 равен отрицательной бесконечности). Когда возникает ошибка особой точки функция возвращает значение (со знаком) HUGE_VAL, HUGE_VALF или HUGE_VALL, в зависимости от типа результата функции — double, float или long double. Знак результата будет математически корректным для функции. Переменной errno присваивается значение ERANGE и возникает исключение плавающей запятой «divide-by-zero» (FE_DIVBYZERO).

  Ошибка диапазона
Ошибка диапазона возникает, когда величина результата функции не может быть представлена типом результата функции. Возвращаемое значение функции зависит от того, было ли при ошибке диапазона переполнение или исчерпание.

Результат с плавающей запятой переполнен, если он является конечным значением, но слишком большим для представления типом результата. При возникновении переполнения функция возвращает значение HUGE_VAL, HUGE_VALF или HUGE_VALL, в зависимости от того, каков тип результата функции — double, float или long double. Переменной errno присваивается значение ERANGE и возникает переполнение плавающей запятой «overflow» (FE_OVERFLOW).

A floating result underflows if the result is too small to be represented in the result type. If an underflow occurs, a mathematical function typically returns 0.0 (C99 says a function shall return "an implementation-defined value whose magnitude is no greater than the smallest normalized positive number in the specified type"). errno may be set to ERANGE, and an "underflow" (FE_UNDERFLOW) floating-point exception may be raised.

Некоторые функции возвращают ошибку диапазона, ели значение аргумента или правильный результат функции был бы субнормальным. Субнормальное значение — ненулевое значение, но его величина так мала, что не может быть представлена в нормализованном виде (т. е., есть 1 с самом значимом бите значащей части). Представление субнормального числа будет содержать один или более начальных нулей в значащей части.

ПРИМЕЧАНИЯ
The math_errhandling identifier specified by C99 and POSIX.1 is not supported by glibc. This identifier is supposed to indicate which of the two error-notification mechanisms (errno, exceptions retrievable via fetestexcept(3)) is in use. The standards require that at least one be in use, but permit both to be available. The current (glibc 2.8) situation under glibc is messy. Most (but not all) functions raise exceptions on errors. Some also set errno. A few functions set errno, but don't raise an exception. A very few functions do neither. See the individual manual pages for details.

Чтобы при проверке ошибок избежать сложностей с использованием errno и fetestexcept(3) часто советуют перед вызовом проверять аргументы на некорректные значения. Например, следующий код проверяет, что аргумент log(3) не равен NaN и не равен нулю (ошибка особой точки) или меньше нуля (ошибка области):

    double x, r;

    if (isnan(x) || islessequal(x, 0)) {
        /* Deal with NaN / pole error / domain error */
    }

    r = log(x);

Данная страница не применима к комплексным математическим функциям (описанным в <complex.h>), для которых в C99 and POSIX.1, обычно, не требуется возвращать ошибки.

Параметр gcc(1) -fno-math-errno заставляет в исполняемых файлах вызывать реализации некоторых математических функций, которые быстрее стандартных, но не изменяющие errno при ошибке (параметр gcc(1) -ffast-math также включает -fno-math-errno.) Возникновение ошибки по-прежнему можно проверить с помощью fetestexcept(3).

СМОТРИТЕ ТАКЖЕ
gcc(1), errno(3), fenv(3), fpclassify(3), INFINITY(3), isgreater(3), matherr(3), nan(3)

info libc

ПЕРЕВОД
Русский перевод этой страницы руководства разработал(и) 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> и Kirill Rekhov <krekhov.dev@gmail.com>

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

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков (<debian-l10n-russian@lists.debian.org>).