1 .\" $NetBSD: fenv.3,v 1.2 2010/08/04 18:58:28 wiz Exp $
2 .\" Copyright (c) 2004 David Schultz <das@FreeBSD.org>
3 .\" All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
8 .\" 1. Redistributions of source code must retain the above copyright
9 .\" notice, this list of conditions and the following disclaimer.
10 .\" 2. Redistributions in binary form must reproduce the above copyright
11 .\" notice, this list of conditions and the following disclaimer in the
12 .\" documentation and/or other materials provided with the distribution.
14 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 .Nd floating-point environment control
49 .Fd "#pragma STDC FENV_ACCESS ON"
51 .Fn feclearexcept "int excepts"
53 .Fn fegetexceptflag "fexcept_t *flagp" "int excepts"
55 .Fn feraiseexcept "int excepts"
57 .Fn fesetexceptflag "const fexcept_t *flagp" "int excepts"
59 .Fn fetestexcept "int excepts"
63 .Fn fesetround "int round"
65 .Fn fegetenv "fenv_t *envp"
67 .Fn feholdexcept "fenv_t *envp"
69 .Fn fesetenv "const fenv_t *envp"
71 .Fn feupdateenv "const fenv_t *envp"
73 .Fn feenableexcept "int excepts"
75 .Fn fedisableexcept "int excepts"
81 routines manipulate the floating-point environment,
82 which includes the exception flags and rounding modes defined in
85 Exception flags are set as side-effects of floating-point arithmetic
86 operations and math library routines, and they remain set until
88 The following macros expand to bit flags of type
90 representing the five standard floating-point exceptions.
91 .Bl -tag -width ".Dv FE_DIVBYZERO"
93 A divide-by-zero exception occurs when the program attempts to
94 divide a finite non-zero number by zero.
96 An inexact exception is raised whenever there is a loss of precision
99 Invalid operation exceptions occur when a program attempts to
100 perform calculations for which there is no reasonable representable
102 For instance, subtraction of infinities, division of zero by zero,
103 ordered comparison involving \*(Nas, and taking the square root of a
104 negative number are all invalid operations.
106 An overflow exception occurs when the magnitude of the result of a
107 computation is too large to fit in the destination type.
109 Underflow occurs when the result of a computation is too close to zero
110 to be represented as a non-zero value in the destination type.
115 macro expands to the bitwise OR of the above flags and any
116 architecture-specific flags.
117 Combinations of these flags are passed to the
119 .Fn fegetexceptflag ,
121 .Fn fesetexceptflag ,
124 functions to clear, save, raise, restore, and examine the
125 processor's floating-point exception flags, respectively.
132 .Fn fedisableexcept .
133 Unmasked exceptions cause a trap when they are produced, and
134 all exceptions are masked by default.
135 The current mask can be tested with
139 specifies four rounding modes.
140 These modes control the direction in which results are rounded
141 from their exact values in order to fit them into binary
142 floating-point variables.
143 The four modes correspond with the following symbolic constants.
144 .Bl -tag -width ".Dv FE_TOWARDZERO"
146 Results are rounded to the closest representable value.
147 If the exact result is exactly half way between two representable
148 values, the value whose last binary digit is even (zero) is chosen.
149 This is the default mode.
151 Results are rounded towards negative \*[If].
153 Results are rounded towards positive \*[If].
155 Results are rounded towards zero.
162 functions query and set the rounding mode.
163 .Ss Environment Control
168 functions save and restore the floating-point environment,
169 which includes exception flags, the current exception mask,
170 the rounding mode, and possibly other implementation-specific
174 function behaves like
176 but with the additional effect of clearing the exception flags and
180 In non-stop mode, floating-point operations will set exception flags
183 signals will be generated as a result.
184 Non-stop mode is the default, but it may be altered by
185 non-standard mechanisms.
186 .\" XXX Mention fe[gs]etmask() here after the interface is finalized
187 .\" XXX and ready to be officially documented.
190 function restores a saved environment similarly to
192 but it also re-raises any floating-point exceptions from the old
197 expands to a pointer to the default environment.
199 The following routine computes the square root function.
200 It explicitly raises an invalid exception on appropriate inputs using
202 It also defers inexact exceptions while it computes intermediate
203 values, and then it allows an inexact exception to be raised only if
204 the final answer is inexact.
205 .Bd -literal -offset indent
206 #pragma STDC FENV_ACCESS ON
207 double sqrt(double n) {
211 if (isnan(n) || n \*[Lt] 0.0) {
212 feraiseexcept(FE_INVALID);
215 if (isinf(n) || n == 0.0)
217 feholdexcept(\*[Am]env);
218 while (fabs((x * x) - n) \*[Gt] DBL_EPSILON * 2 * x)
219 x = (x / 2) + (n / (2 * x));
221 feclearexcept(FE_INEXACT);
222 feupdateenv(\*[Am]env);
228 .Xr feclearexcept 3 ,
229 .Xr fedisableexcept 3 ,
230 .Xr feenableexcept 3 ,
233 .Xr fegetexceptflag 3 ,
236 .Xr feraiseexcept 3 ,
238 .Xr fesetexceptflag 3 ,
245 Except as noted below,
251 .Fn fedisableexcept ,
254 routines are extensions.
258 header first appeared in
262 It supersedes the non-standard routines defined in
267 The FENV_ACCESS pragma can be enabled with
268 .Dl "#pragma STDC FENV_ACCESS ON"
269 and disabled with the
270 .Dl "#pragma STDC FENV_ACCESS OFF"
272 This lexically-scoped annotation tells the compiler that the program
273 may access the floating-point environment, so optimizations that would
274 violate strict IEEE-754 semantics are disabled.
275 If execution reaches a block of code for which
277 is off, the floating-point environment will become undefined.
281 pragma is unimplemented in the system compiler.
282 However, non-constant expressions generally produce the correct
283 side-effects at low optimization levels.