xref: /freebsd/lib/msun/man/fenv.3 (revision 315ee00f)
1.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.Dd March 16, 2005
26.Dt FENV 3
27.Os
28.Sh NAME
29.Nm feclearexcept ,
30.Nm fegetexceptflag ,
31.Nm feraiseexcept ,
32.Nm fesetexceptflag ,
33.Nm fetestexcept ,
34.Nm fegetround ,
35.Nm fesetround ,
36.Nm fegetenv ,
37.Nm feholdexcept ,
38.Nm fesetenv ,
39.Nm feupdateenv ,
40.Nm feenableexcept ,
41.Nm fedisableexcept ,
42.Nm fegetexcept
43.Nd floating-point environment control
44.Sh LIBRARY
45.Lb libm
46.Sh SYNOPSIS
47.In fenv.h
48.Fd "#pragma STDC FENV_ACCESS ON"
49.Ft int
50.Fn feclearexcept "int excepts"
51.Ft int
52.Fn fegetexceptflag "fexcept_t *flagp" "int excepts"
53.Ft int
54.Fn feraiseexcept "int excepts"
55.Ft int
56.Fn fesetexceptflag "const fexcept_t *flagp" "int excepts"
57.Ft int
58.Fn fetestexcept "int excepts"
59.Ft int
60.Fn fegetround void
61.Ft int
62.Fn fesetround "int round"
63.Ft int
64.Fn fegetenv "fenv_t *envp"
65.Ft int
66.Fn feholdexcept "fenv_t *envp"
67.Ft int
68.Fn fesetenv "const fenv_t *envp"
69.Ft int
70.Fn feupdateenv "const fenv_t *envp"
71.Ft int
72.Fn feenableexcept "int excepts"
73.Ft int
74.Fn fedisableexcept "int excepts"
75.Ft int
76.Fn fegetexcept void
77.Sh DESCRIPTION
78The
79.In fenv.h
80routines manipulate the floating-point environment,
81which includes the exception flags and rounding modes defined in
82.St -ieee754 .
83.Ss Exceptions
84Exception flags are set as side-effects of floating-point arithmetic
85operations and math library routines, and they remain set until
86explicitly cleared.
87The following macros expand to bit flags of type
88.Vt int
89representing the five standard floating-point exceptions.
90.Bl -tag -width ".Dv FE_DIVBYZERO"
91.It Dv FE_DIVBYZERO
92A divide-by-zero exception occurs when the
93.Em exact
94result of a computation is infinite (according to the limit definition).
95For example, dividing a finite non-zero number by zero or computing
96.Fn log 0
97raises a divide-by-zero exception.
98.It Dv FE_INEXACT
99An inexact exception is raised whenever there is a loss of accuracy
100due to rounding.
101.It Dv FE_INVALID
102Invalid operation exceptions occur when a program attempts to
103perform calculations for which there is no reasonable representable
104answer.
105For instance, subtraction of like-signed infinities, division of zero by zero,
106ordered comparison involving \*(Nas, and taking the real square root of a
107negative number are all invalid operations.
108.It Dv FE_OVERFLOW
109In contrast with divide-by-zero,
110an overflow exception occurs when an infinity is produced because
111the magnitude of the exact result is
112.Em finite
113but too large to fit in the destination type.
114For example, computing
115.Li DBL_MAX * 2
116raises an overflow exception.
117.It Dv FE_UNDERFLOW
118Underflow occurs when the result of a computation loses precision
119because it is too close to zero.
120The result is a subnormal number or zero.
121.El
122.Pp
123Additionally, the
124.Dv FE_ALL_EXCEPT
125macro expands to the bitwise OR of the above flags and any
126architecture-specific flags.
127Combinations of these flags are passed to the
128.Fn feclearexcept ,
129.Fn fegetexceptflag ,
130.Fn feraiseexcept ,
131.Fn fesetexceptflag ,
132and
133.Fn fetestexcept
134functions to clear, save, raise, restore, and examine the
135processor's floating-point exception flags, respectively.
136.Pp
137Exceptions may be
138.Em unmasked
139with
140.Fn feenableexcept
141and masked with
142.Fn fedisableexcept .
143Unmasked exceptions cause a trap when they are produced, and
144all exceptions are masked by default.
145The current mask can be tested with
146.Fn fegetexcept .
147.Ss Rounding Modes
148.St -ieee754
149specifies four rounding modes.
150These modes control the direction in which results are rounded
151from their exact values in order to fit them into binary
152floating-point variables.
153The four modes correspond with the following symbolic constants.
154.Bl -tag -width ".Dv FE_TOWARDZERO"
155.It Dv FE_TONEAREST
156Results are rounded to the closest representable value.
157If the exact result is exactly half way between two representable
158values, the value whose last binary digit is even (zero) is chosen.
159This is the default mode.
160.It Dv FE_DOWNWARD
161Results are rounded towards negative \*[If].
162.It Dv FE_UPWARD
163Results are rounded towards positive \*[If].
164.It Dv FE_TOWARDZERO
165Results are rounded towards zero.
166.El
167.Pp
168The
169.Fn fegetround
170and
171.Fn fesetround
172functions query and set the rounding mode.
173.Ss Environment Control
174The
175.Fn fegetenv
176and
177.Fn fesetenv
178functions save and restore the floating-point environment,
179which includes exception flags, the current exception mask,
180the rounding mode, and possibly other implementation-specific
181state.
182The
183.Fn feholdexcept
184function behaves like
185.Fn fegetenv ,
186but with the additional effect of clearing the exception flags and
187installing a
188.Em non-stop
189mode.
190In non-stop mode, floating-point operations will set exception flags
191as usual, but no
192.Dv SIGFPE
193signals will be generated as a result.
194Non-stop mode is the default, but it may be altered by
195.Fn feenableexcept
196and
197.Fn fedisableexcept .
198The
199.Fn feupdateenv
200function restores a saved environment similarly to
201.Fn fesetenv ,
202but it also re-raises any floating-point exceptions from the old
203environment.
204.Pp
205The macro
206.Dv FE_DFL_ENV
207expands to a pointer to the default environment.
208.Sh EXAMPLES
209The following routine computes the square root function.
210It explicitly raises an invalid exception on appropriate inputs using
211.Fn feraiseexcept .
212It also defers inexact exceptions while it computes intermediate
213values, and then it allows an inexact exception to be raised only if
214the final answer is inexact.
215.Bd -literal -offset indent
216#pragma STDC FENV_ACCESS ON
217double sqrt(double n) {
218	double x = 1.0;
219	fenv_t env;
220
221	if (isnan(n) || n < 0.0) {
222		feraiseexcept(FE_INVALID);
223		return (NAN);
224	}
225	if (isinf(n) || n == 0.0)
226		return (n);
227	feholdexcept(&env);
228	while (fabs((x * x) - n) > DBL_EPSILON * 2 * x)
229		x = (x / 2) + (n / (2 * x));
230	if (x * x == n)
231		feclearexcept(FE_INEXACT);
232	feupdateenv(&env);
233	return (x);
234}
235.Ed
236.Sh SEE ALSO
237.Xr cc 1 ,
238.Xr feclearexcept 3 ,
239.Xr fedisableexcept 3 ,
240.Xr feenableexcept 3 ,
241.Xr fegetenv 3 ,
242.Xr fegetexcept 3 ,
243.Xr fegetexceptflag 3 ,
244.Xr fegetround 3 ,
245.Xr feholdexcept 3 ,
246.Xr feraiseexcept 3 ,
247.Xr fesetenv 3 ,
248.Xr fesetexceptflag 3 ,
249.Xr fesetround 3 ,
250.Xr fetestexcept 3 ,
251.Xr feupdateenv 3 ,
252.Xr fpgetprec 3 ,
253.Xr fpsetprec 3
254.Sh STANDARDS
255Except as noted below,
256.In fenv.h
257conforms to
258.St -isoC-99 .
259The
260.Fn feenableexcept ,
261.Fn fedisableexcept ,
262and
263.Fn fegetexcept
264routines are extensions.
265.Sh HISTORY
266The
267.In fenv.h
268header first appeared in
269.Fx 5.3 .
270It supersedes the non-standard routines defined in
271.In ieeefp.h
272and documented in
273.Xr fpgetround 3 .
274.Sh CAVEATS
275The FENV_ACCESS pragma can be enabled with
276.Dl "#pragma STDC FENV_ACCESS ON"
277and disabled with the
278.Dl "#pragma STDC FENV_ACCESS OFF"
279directive.
280This lexically-scoped annotation tells the compiler that the program
281may access the floating-point environment, so optimizations that would
282violate strict IEEE-754 semantics are disabled.
283If execution reaches a block of code for which
284.Dv FENV_ACCESS
285is off, the floating-point environment will become undefined.
286.Sh BUGS
287The
288.Dv FENV_ACCESS
289pragma is unimplemented in the system compiler.
290However, non-constant expressions generally produce the correct
291side-effects at low optimization levels.
292