FENV(3)

NOME
feclearexcept, fegetexceptflag, feraiseexcept, fesetexceptflag, fetestexcept, fegetenv, fegetround, feholdexcept, fesetround, fesetenv, feupdateenv - tratamento de exceção e arredondamento de ponto flutuante do C99

SINÓPSE
#include <fenv.h>

void feclearexcept(int excepts);
void fegetexceptflag(fexcept_t *flagp, int excepts);
void feraiseexcept(int excepts);
void fesetexceptflag(const fexcept_t *flagp, int excepts);
int fetestexcept(int excepts);

int fegetround(void);
int fesetround(int rounding_mode);

void fegetenv(fenv_t *envp);
int feholdexcept(fenv_t *envp);
void fesetenv(const fenv_t *envp);
void feupdateenv(const fenv_t *envp);

DESCRIÇÃO
Estas onze funções foram definidas no C99, e descrevem o tratamento de arredondamento e exceções de ponto flutuante (estouro de representação, divisão por zero, etc.).

  Exceções
A exceção DivideByZero ocorre quando uma operação sobre números finitos produz infinito como resposta exata.

A exceção Overflow ocorre quando um resultado tem de ser representado como um número de ponto flutuante, mas tem valor absoluto (muito) maior que o maior número de ponto flutuante (finito) que é representável.

A exceção Underflow ocorre quando um resultado tem de ser representado como um número de ponto flutuante, mas tem valor absoluto menor que o menor número de ponto flutuante positivo normalizado (e perderia muita precisão se representado como um número denormalizado).

A exceção Inexact ocorre quando o resultado arredondado de uma operação não é igual ao resultado de precisão infinita. Ela pode ocorrer quando quer que Overflow ou Underflow ocorram.

A exceção Invalid ocorre quando não há resultado bem definido para uma operação, como para 0/0 ou infinito - infinito ou sqrt(-1).

  Tratamento de Exceções
Exceções são representadas de duas formas: como um único bit (exceção presente/ausente), e esses bits correspondem em alguma forma definida pela implementação com posições de bit em um inteiro, e também como uma estrutura opaca que pode conter mais informação sobre a exceção (talvez o endereço de código onde ela ocorreu).

Cada uma das macros FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW, FE_UNDERFLOW é definida quando a implementação suporta tratamento da exceção correspondente, e, se sim, então define o(s) bit(s) correspondente(s), de forma que se possa chamar funções de tratamento de exceções, por exemplo, usando o argumento inteiro FE_OVERFLOW|FE_UNDERFLOW. Outras exceções podem ser suportadas. A macro FE_ALL_EXCEPT é o OR bit a bit de todos os bits correspondendo a exceções suportadas.

A função feclearexcept desabilita as exceções suportadas representadas pelos bits no seu argumento.

A função fegetexceptflag armazena uma representação do estado dos indicadores de exceção representados pelo argumento excepts no objeto opaco *flagp.

A função feraiseexcept dispara as exceções suportadas representadas pelos bits em excepts.

A função fesetexceptflag define o estado completo para as exceções representadas por excepts para o valor *flagp. Esse valor deve ter sido obtido por uma chamada anterior a fegetexceptflag com um último argumento que contivesse todos os bits em excepts.

A função fetestexcept retorna uma palavra na qual os bits definidos são os definidos no argumento excepts e para os quais a exceção correspondente está atualmente habilitada.

  Arredondamento
Cada uma das macros FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD é definida quando a implementação suporta obter e definir a direção de arredondamento correspondente.

A função fegetround retorna a macro correspondente ao modo de arredondamento atual.

A função fesetround define o modo de arredondamento como especificado por seu argumento e retorna zero quando for bem sucedida.

  Ambiente de Ponto Flutuante
O ambiente de ponto flutuante inteiro, incluindo modos de controle e indicadores de estado, pode ser tratado como um objeto opaco, de tipo fenv_t. O ambiente padrão é denotado por FE_DFL_ENV (de tipo const fenv_t *). Essa é a definição do ambiente ao início do programa e é definida por ISO C como tendo arredondamento para o mais próximo, todas as exceções desabilitadas e um modo 'non-stop' (continuar nas exceções).

A função fegetenv salva o ambiente de ponto flutuante atual no objeto *envp.

A função feholdexcept faz o mesmo, então zera todos indicadores de exceção, e define um modo 'non-stop' (continuar nas exceções), se disponível. Ela retorna zero quando bem sucedida.

A função fesetenv restaura o ambiente de ponto flutuante do objeto *envp. Esse objeto deve ser reconhecidamente válido, por exemplo, o resultado de uma chamada a fegetenv ou feholdexcept ou igual a FE_DFL_ENV. Essa chamada não dispara exceções.

A função feupdateenv instala o ambiente de ponto flutuante representado pelo objeto *envp, exceto que as exceções que estão atualmente disparadas não são desabilitadas. Depois de chamar essa função, as exceções disparadas serão o OR bit a bit daquelas previamente definidas com aquelas em *envp. Como antes, o objeto *envp deve ser reconhecido como sendo válido.

DETALHES GNU
Se possível, a Biblioteca C GNU define a macro FE_NOMASK_ENV a qual representa um ambiente em que toda exceção disparada causa a ocorrência de uma captura. Você pode testar por essa macro usando #ifdef. Ela só é definida se _GNU_SOURCE estiver definida. O padrão C99 não define uma forma de definir bits individuais na máscara de ponto flutuante, por exemplo, para capturar quando de indicadores específicos. glibc 2.2 suportará as funções feenableexcept e fedisableexcept para definir capturas de ponto flutuante individuais, e fegetexcept para obter o estado.

int feenableexcept (int excepts);
int fedisableexcept (int excepts);
int fegetexcept (void);

As funções feenableexcept e fedisableexcept habilitam (desabilitam) capturas para cada uma das exceções representadas por excepts e retornam o conjunto anterior de exceções habilitadas quando bem sucedida, e -1 caso contrário. A função fegetexcept retorna o conjunto de todas as exceções atualmente habilitadas.

DE ACORDO COM
IEC 60559 (IEC 559:1989), ANSI/IEEE 854, ISO C99 (ISO/IEC 9899:1999).

TRADUZIDO POR LDP-BR em 13/06/2001.

  Tradução:
Marcelo M. de Abreu <mmabreu@terra.com.br>

  Revisão.:
André Luiz Fassone <lonely_wolf@ig.com.br>