Стандарт языка Си С99 TC (1113411), страница 38
Текст из файла (страница 38)
Also it isdesigned to facilitate code portability among all systems.179) A floating-point status flag is not an object and can be set more than once within an expression.180) With these conventions, a programmer can safely assume default floating-point control modes (or beunaware of them). The responsibilities associated with accessing the floating-point environment fallon the programmer or program that does so explicitly.§7.6Library187ISO/IEC 9899:TC35Committee Draft — Septermber 7, 2007WG14/N1256Each of the macrosFE_DIVBYZEROFE_INEXACTFE_INVALIDFE_OVERFLOWFE_UNDERFLOWis defined if and only if the implementation supports the floating-point exception bymeans of the functions in 7.6.2.181) Additional implementation-defined floating-pointexceptions, with macro definitions beginning with FE_ and an uppercase letter, may alsobe specified by the implementation.
The defined macros expand to integer constantexpressions with values such that bitwise ORs of all combinations of the macros result indistinct values, and furthermore, bitwise ANDs of all combinations of the macros result inzero.182)6The macroFE_ALL_EXCEPTis simply the bitwise OR of all floating-point exception macros defined by theimplementation. If no such macros are defined, FE_ALL_EXCEPT shall be defined as 0.7Each of the macrosFE_DOWNWARDFE_TONEARESTFE_TOWARDZEROFE_UPWARDis defined if and only if the implementation supports getting and setting the representedrounding direction by means of the fegetround and fesetround functions.Additional implementation-defined rounding directions, with macro definitions beginningwith FE_ and an uppercase letter, may also be specified by the implementation.
Thedefined macros expand to integer constant expressions whose values are distinctnonnegative values.183)8The macro181) The implementation supports an exception if there are circumstances where a call to at least one of thefunctions in 7.6.2, using the macro as the appropriate argument, will succeed. It is not necessary forall the functions to succeed all the time.182) The macros should be distinct powers of two.183) Even though the rounding direction macros may expand to constants corresponding to the values ofFLT_ROUNDS, they are not required to do so.188Library§7.6WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3FE_DFL_ENVrepresents the default floating-point environment — the one installed at program startup— and has type ‘‘pointer to const-qualified fenv_t’’.
It can be used as an argument to<fenv.h> functions that manage the floating-point environment.9Additional implementation-defined environments, with macro definitions beginning withFE_ and an uppercase letter, and having type ‘‘pointer to const-qualified fenv_t’’, mayalso be specified by the implementation.7.6.1 The FENV_ACCESS pragmaSynopsis1#include <fenv.h>#pragma STDC FENV_ACCESS on-off-switchDescription2The FENV_ACCESS pragma provides a means to inform the implementation when aprogram might access the floating-point environment to test floating-point status flags orrun under non-default floating-point control modes.184) The pragma shall occur eitheroutside external declarations or preceding all explicit declarations and statements inside acompound statement.
When outside external declarations, the pragma takes effect fromits occurrence until another FENV_ACCESS pragma is encountered, or until the end ofthe translation unit. When inside a compound statement, the pragma takes effect from itsoccurrence until another FENV_ACCESS pragma is encountered (including within anested compound statement), or until the end of the compound statement; at the end of acompound statement the state for the pragma is restored to its condition just before thecompound statement. If this pragma is used in any other context, the behavior isundefined.
If part of a program tests floating-point status flags, sets floating-point controlmodes, or runs under non-default mode settings, but was translated with the state for theFENV_ACCESS pragma ‘‘off’’, the behavior is undefined. The default state (‘‘on’’ or‘‘off’’) for the pragma is implementation-defined.
(When execution passes from a part ofthe program translated with FENV_ACCESS ‘‘off’’ to a part translated withFENV_ACCESS ‘‘on’’, the state of the floating-point status flags is unspecified and thefloating-point control modes have their default settings.)184) The purpose of the FENV_ACCESS pragma is to allow certain optimizations that could subvert flagtests and mode changes (e.g., global common subexpression elimination, code motion, and constantfolding). In general, if the state of FENV_ACCESS is ‘‘off’’, the translator can assume that defaultmodes are in effect and the flags are not tested.§7.6.1Library189ISO/IEC 9899:TC33Committee Draft — Septermber 7, 2007WG14/N1256EXAMPLE#include <fenv.h>void f(double x){#pragma STDC FENV_ACCESS ONvoid g(double);void h(double);/* ...
*/g(x + 1);h(x + 1);/* ... */}4If the function g might depend on status flags set as a side effect of the first x + 1, or if the secondx + 1 might depend on control modes set as a side effect of the call to function g, then the program shallcontain an appropriately placed invocation of #pragma STDC FENV_ACCESS ON.185)7.6.2 Floating-point exceptions1The following functions provide access to the floating-point status flags.186) The intinput argument for the functions represents a subset of floating-point exceptions, and canbe zero or the bitwise OR of one or more floating-point exception macros, for exampleFE_OVERFLOW | FE_INEXACT.
For other argument values the behavior of thesefunctions is undefined.7.6.2.1 The feclearexcept functionSynopsis1#include <fenv.h>int feclearexcept(int excepts);Description2The feclearexcept function attempts to clear the supported floating-point exceptionsrepresented by its argument.Returns3The feclearexcept function returns zero if the excepts argument is zero or if allthe specified exceptions were successfully cleared. Otherwise, it returns a nonzero value.185) The side effects impose a temporal ordering that requires two evaluations of x + 1. On the otherhand, without the #pragma STDC FENV_ACCESS ON pragma, and assuming the default state is‘‘off’’, just one evaluation of x + 1 would suffice.186) The functions fetestexcept, feraiseexcept, and feclearexcept support the basicabstraction of flags that are either set or clear. An implementation may endow floating-point statusflags with more information — for example, the address of the code which first raised the floatingpoint exception; the functions fegetexceptflag and fesetexceptflag deal with the fullcontent of flags.190Library§7.6.2.1WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC37.6.2.2 The fegetexceptflag functionSynopsis1#include <fenv.h>int fegetexceptflag(fexcept_t *flagp,int excepts);Description2The fegetexceptflag function attempts to store an implementation-definedrepresentation of the states of the floating-point status flags indicated by the argumentexcepts in the object pointed to by the argument flagp.Returns3The fegetexceptflag function returns zero if the representation was successfullystored.
Otherwise, it returns a nonzero value.7.6.2.3 The feraiseexcept functionSynopsis1#include <fenv.h>int feraiseexcept(int excepts);Description2The feraiseexcept function attempts to raise the supported floating-point exceptionsrepresented by its argument.187) The order in which these floating-point exceptions areraised is unspecified, except as stated in F.7.6. Whether the feraiseexcept functionadditionally raises the ‘‘inexact’’ floating-point exception whenever it raises the‘‘overflow’’ or ‘‘underflow’’ floating-point exception is implementation-defined.Returns3The feraiseexcept function returns zero if the excepts argument is zero or if allthe specified exceptions were successfully raised. Otherwise, it returns a nonzero value.187) The effect is intended to be similar to that of floating-point exceptions raised by arithmetic operations.Hence, enabled traps for floating-point exceptions raised by this function are taken.
The specificationin F.7.6 is in the same spirit.§7.6.2.3Library191ISO/IEC 9899:TC3Committee Draft — Septermber 7, 2007WG14/N12567.6.2.4 The fesetexceptflag functionSynopsis1#include <fenv.h>int fesetexceptflag(const fexcept_t *flagp,int excepts);Description2The fesetexceptflag function attempts to set the floating-point status flagsindicated by the argument excepts to the states stored in the object pointed to byflagp. The value of *flagp shall have been set by a previous call tofegetexceptflag whose second argument represented at least those floating-pointexceptions represented by the argument excepts. This function does not raise floatingpoint exceptions, but only sets the state of the flags.Returns3The fesetexceptflag function returns zero if the excepts argument is zero or ifall the specified flags were successfully set to the appropriate state.
Otherwise, it returnsa nonzero value.7.6.2.5 The fetestexcept functionSynopsis1#include <fenv.h>int fetestexcept(int excepts);Description2The fetestexcept function determines which of a specified subset of the floatingpoint exception flags are currently set.
The excepts argument specifies the floatingpoint status flags to be queried.188)Returns3The fetestexcept function returns the value of the bitwise OR of the floating-pointexception macros corresponding to the currently set floating-point exceptions included inexcepts.4EXAMPLECall f if ‘‘invalid’’ is set, then g if ‘‘overflow’’ is set:188) This mechanism allows testing several floating-point exceptions with just one function call.192Library§7.6.2.5WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3#include <fenv.h>/* ... */{#pragma STDC FENV_ACCESS ONint set_excepts;feclearexcept(FE_INVALID | FE_OVERFLOW);// maybe raise exceptionsset_excepts = fetestexcept(FE_INVALID | FE_OVERFLOW);if (set_excepts & FE_INVALID) f();if (set_excepts & FE_OVERFLOW) g();/* ... */}7.6.3 Rounding1The fegetround and fesetround functions provide control of rounding directionmodes.7.6.3.1 The fegetround functionSynopsis1#include <fenv.h>int fegetround(void);Description2The fegetround function gets the current rounding direction.Returns3The fegetround function returns the value of the rounding direction macrorepresenting the current rounding direction or a negative value if there is no suchrounding direction macro or the current rounding direction is not determinable.7.6.3.2 The fesetround functionSynopsis1#include <fenv.h>int fesetround(int round);Description2The fesetround function establishes the rounding direction represented by itsargument round.
If the argument is not equal to the value of a rounding direction macro,the rounding direction is not changed.Returns3The fesetround function returns zero if and only if the requested rounding directionwas established.§7.6.3.2Library193ISO/IEC 9899:TC34Committee Draft — Septermber 7, 2007WG14/N1256EXAMPLE Save, set, and restore the rounding direction. Report an error and abort if setting therounding direction fails.#include <fenv.h>#include <assert.h>void f(int round_dir){#pragma STDC FENV_ACCESS ONint save_round;int setround_ok;save_round = fegetround();setround_ok = fesetround(round_dir);assert(setround_ok == 0);/* ...