feclearexcept, fegetexceptflag, feraiseexcept, fesetexceptflag, fetestexcept,
fegetenv, fegetround, feholdexcept, fesetround, fesetenv, feupdateenv,
feenableexcept, fedisableexcept, fegetexcept -
округление
и
обработка
ошибок для
чисел с
плавающей
запятой
Math library (
libm,
-lm)
#include <fenv.h>
int feclearexcept(int excepts);
int fegetexceptflag(fexcept_t *flagp, int excepts);
int feraiseexcept(int excepts);
int fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexcept(int excepts);
int fegetround(void);
int fesetround(int rounding_mode);
int fegetenv(fenv_t *envp);
int feholdexcept(fenv_t *envp);
int fesetenv(const fenv_t *envp);
int feupdateenv(const fenv_t *envp);
Эти
одиннадцать
функций
определены
в C99, и
описывают
обработку
округления
и
исключения
(переполнение,
деление на
ноль и т. д.)
при работе
с числами с
плавающей
запятой.
Исключение
деление-на-ноль
(divide-by-zero)
возникает,
когда
результатом
операции
над
конечными
числами
является
бесконечность.
Исключение
переполнение
(overflow)
возникает,
когда
результат
возможно
представить
в виде
числа с
плавающей
запятой, но
он намного
больше
абсолютного
значения
самого
большого
(конечного)
представимого
числа с
плавающей
запятой.
Исключение
исчерпания(underflow)
возникает,
когда
результат
можно
представить
в виде
числа с
плавающей
запятой, но
он меньше
абсолютного
значения
самого
малого
положительного
нормализованного
числа с
плавающей
запятой (и
возникает
большая
потеря
точности,
если
представить
его в виде
денормализованного
числа).
Исключение
inexact
возникает,
когда
округлённый
результат
операции
не равен
бесконечной
точности
результата.
Оно может
произойти
при
исключении
переполнении
или
исчерпании.
Исключение
invalid
возникает,
когда при
операции
получается
плохо
определённый
результат (no
well-defined result),
например,
при 0/0 или
бесконечность
-
бесконечность
или sqrt(-1).
Исключения
представляются
двумя
способами:
в виде
одного
бита
(наличие/отсутствие
исключения)
и целого
числа, где
каждый бит
соответствует
исключению
(определяется
реализацией),
а также
структуры
скрытого
формата,
которая
может
содержать
дополнительную
информацию
об
исключении
(возможно,
адрес в
коде, где
оно
возникло).
Если
реализацией
поддерживается
обработка
определённого
исключения,
то
определён
соответствующий
макрос:
FE_DIVBYZERO,
FE_INEXACT,
FE_INVALID,
FE_OVERFLOW,
FE_UNDERFLOW.
Если таким
способом
определить
соответствующий
бит(ы),
например, с
целочисленным
аргументом
FE_OVERFLOW|
FE_UNDERFLOW, то
могут
вызываться
функции
обработки
исключений.
Могут
поддерживаться
и другие
исключения.
Макрос
FE_ALL_EXCEPT —
это
побитовый OR
всех бит,
соответствующих
поддерживаемым
исключениям.
Функция
feclearexcept()
очищает
поддерживаемые
исключения,
указанные
битами в
аргументе.
Функция
fegetexceptflag()
сохраняет
представление
состояния
флагов
исключения,
представленного
аргументом
excepts в чёрном
ящике
*flagp.
Функция
feraiseexcept()
возбуждает
поддерживаемые
исключения,
заданные
битами в
excepts.
Функция
fesetexceptflag() задаёт
полное
состояние
для
исключений,
представленных
в
excepts, в
значение
*flagp. Это
значение
должно
быть
получено с
помощью
вызова
fegetexceptflag()
с
последним
аргументом,
значение
которого
содержит
все биты в
excepts.
Функция
fetestexcept()
возвращает
слово, в
котором
биты
устанавливаются
в
соответствии
с
установленными
битами в
аргументе
excepts и для
которых
установлено
соответствующее
исключение.
Режим
округления
определяет
трактовку
результата
операций с
плавающей
запятой,
если
результат
не может
быть точно
представлен
в значащей
части
числа(significand).
Могут быть
доступны
различные
режимы
округления:
округление
к
ближайшему
(по
умолчанию),
округление
в сторону
увеличения
(round up, к
положительной
бесконечности),
округление
в сторону
уменьшения
(round down, к
отрицательной
бесконечности)
и
округление
в сторону
нуля.
Если в
реализации
поддерживается
получение
и
установка
направления
округления,
то для них
определены
соответствующие
макросы:
FE_TONEAREST,
FE_UPWARD,
FE_DOWNWARD и
FE_TOWARDZERO.
Функция
fegetround()
возвращает
макрос,
соответствующий
текущему
режиму
округления.
Функция
fesetround()
задаёт
режим
округления
в
соответствии
со
значением
аргумента
и
возвращает
ноль при
успешном
выполнении.
В C99 и POSIX.1-2008 в
файле
<float.h>
описан
идентификатор
FLT_ROUNDS, который
определяет
используемый
реализацией
режим
поведения
для
сложения
чисел с
плавающей
запятой.
Значениями
идентификатора
могут быть:
- -1
- Режим
округления
не
определён.
- 0
- Округление
к нулю.
- 1
- Округление
к
ближайшему
числу.
- 2
- Округление
в сторону
положительной
бесконечности.
- 3
- Округление
в сторону
отрицательной
бесконечности.
Существуют
другие
значения
для
нестандартных
режимов
округления,
зависящие
от
архитектуры.
Значение
FLT_ROUNDS должно
отражать
текущий
режим
округления,
который
задаётся с
помощью
fesetround()
(но
смотрите
ДЕФЕКТЫ).
С полным
окружением
плавающей
запятой,
включая
режимы
управления
и флаги
состояния,
можно
работать
через
скрытый
объект с
типом
fenv_t.
Окружение
по
умолчанию
обозначается
как
FE_DFL_ENV (с
типом
const fenv_t *).
Это
окружение
задаётся
при
запуске
программы
и
определено
в ISO C; в нём
включено
округление
к
ближайшему
числу, все
исключения
сброшены и
задан
безостановочный
режим
(продолжать
при
возникновении
исключений).
Функция
fegetenv()
сохраняет
текущее
окружение
плавающей
запятой в
объект
*envp.
Функция
feholdexcept()
делает то
же самое,
затем
очищает
все флаги
исключений
и включает
безостановочный
режим
(продолжать
при
возникновении
исключений),
если он
доступен.
При
успешном
выполнении
возвращается
ноль.
Функция
fesetenv()
восстанавливает
окружение
плавающей
запятой из
объекта
*envp.
Данный
объект
должен
быть
корректен,
например,
должен
быть
получен из
вызова
fegetenv()
или
feholdexcept() или
равен
FE_DFL_ENV.
Данный
вызов не
возбуждает
исключения.
Функция
feupdateenv()
устанавливает
окружение
плавающей
запятой,
представленное
объектом
*envp,
за
исключением
того, что
уже
возбуждённые
исключения
не
очищаются.
После
вызова
этой
функции,
возбуждённые
исключения
будут
побитово
сложены с
установленными
ранее в
*envp.
Как и для
предыдущей
функции,
объект
*envp
должен
быть
корректен.
При
успешном
выполнении
эти
функции
возвращают
ноль и не
ноль при
ошибке.
These functions were added in glibc 2.1.
Описание
терминов
данного
раздела
смотрите в
attributes(7).
Интерфейс |
Атрибут |
Значение |
feclearexcept(), fegetexceptflag(),
feraiseexcept(), fesetexceptflag(), fetestexcept(),
fegetround(), fesetround(), fegetenv(),
feholdexcept(), fesetenv(), feupdateenv(),
feenableexcept(), fedisableexcept(),
fegetexcept() |
Безвредность
в нитях |
MT-Safe |
IEC 60559 (IEC 559:1989), ANSI/IEEE 854, C99, POSIX.1-2001.
If possible, the GNU C Library defines a macro
FE_NOMASK_ENV which
represents an environment where every exception raised causes a trap to occur.
You can test for this macro using
#ifdef. It is defined only if
_GNU_SOURCE is defined. The C99 standard does not define a way to set
individual bits in the floating-point mask, for example, to trap on specific
flags. Since glibc 2.2, glibc supports the functions
feenableexcept()
and
fedisableexcept() to set individual floating-point traps, and
fegetexcept() to query the state.
#define _GNU_SOURCE /* смотрите feature_test_macros(7) */
#include <fenv.h>
int feenableexcept(int excepts);
int fedisableexcept(int excepts);
int fegetexcept(void);
Функции
feenableexcept()
и
fedisableexcept()
включают
(отключают)
ловушки
для
каждого
исключения,
представленного
в
excepts, и при
успешном
выполнении
возвращают
старый
набор
включённых
исключений,
и -1 в
противном
случае.
Функция
fegetexcept()
возвращает
набор всех
включённых
в данных
момент
исключений.
В C99 указано,
что
значение
FLT_ROUNDS должно
отражать
изменения
текущего
режима
округления,
устанавливаемого
с помощью
fesetround(). В
настоящее
время это
не
выполняется:
значение
FLT_ROUNDS всегда
равно 1.
math_error(7)
Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <
[email protected]>, Dmitry Bolkhovskikh
<
[email protected]>, Yuri Kozlov <
[email protected]> и
Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]