table of contents
fenv(3) | Library Functions Manual | fenv(3) |
ИМЯ¶
feclearexcept, fegetexceptflag, feraiseexcept, fesetexceptflag, fetestexcept, fegetenv, fegetround, feholdexcept, fesetround, fesetenv, feupdateenv, feenableexcept, fedisableexcept, fegetexcept - округление и обработка ошибок для чисел с плавающей запятой
LIBRARY¶
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 должен быть корректен.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении эти функции возвращают ноль и не ноль при ошибке.
АТРИБУТЫ¶
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
feclearexcept(), fegetexceptflag(), feraiseexcept(), fesetexceptflag(), fetestexcept(), fegetround(), fesetround(), fegetenv(), feholdexcept(), fesetenv(), feupdateenv(), feenableexcept(), fedisableexcept(), fegetexcept() | Безвредность в нитях | MT-Safe |
СТАНДАРТЫ¶
C11, POSIX.1-2008, IEC 60559 (IEC 559:1989), ANSI/IEEE 854.
ИСТОРИЯ¶
C99, POSIX.1-2001. glibc 2.1.
ПРИМЕЧАНИЯ¶
Замечания по glibc¶
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.
СМОТРИТЕ ТАКЖЕ¶
ПЕРЕВОД¶
Русский перевод этой страницы руководства разработал Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.
2 мая 2024 г. | Linux man-pages (unreleased) |